dva是一个很好用的状态管理框架,
最近遇到了一个就是
当改变models中的state时,props中数据改变但不触发render事件导致页面无法再次更新渲染
贴上错误代码:
models文件:
state: {
items: [],//是一个引用数据类型,除了基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6)之外都是
},
reducers: {
save(state, { params }) {
return { ...state, items: params };
},
引用文件:
add = ()=>{
let {items} = this.props
items.push({
a:1,
b:2,
node:this.getNode
});
this.props.dispatch({
type: 'model/save',
params: items,
});
}
getNode = (item,index)=>{
return <div>{index}</div>
}
render函数
{this.props.items.map((item: any, index: number) => {
return item.node(item, index);
})}
然后你就会发现 当你通过按钮调用add函数的时候
屏幕一直是 为零 0,
所以这就出现一个问题,为什么props中数据改变但不触发render事件导致页面无法再次更新渲染,
原因:
如果这个props如果是引用数据类型的话,当这个引用数据类型的地址不发生变化时,
是不会触发componentWillReceiveProps,引发render函数的重新执行"
解决方案:
通过深拷贝,重新给items复制到一个新的堆栈,
let items = JSON,parse(JSON.stringify(this.props.items))//比较常用
这样子就可以了
但是JSON.parse,JSON.stringify也有引发另一个问题就是:
他无法拷贝函数,(补充:时间对象会变成 字符串 的形式、RegExp,Error、函数会丢失)
所以我就这样子,拷贝后再赋值给他
let items:any = JSON.parse(JSON.stringify(this.props.items))
for(let key in items){
items[key].node=this.getNode
}
items.push(obj);
this.props.dispatch({
type: 'model/save',
params: items,
});
}
如果有其他比较好的方法也很欢迎大家留言,一起学习进步