众所周知,使react组件重新渲染的三种方式:
1、setState()
2、props发生变化
3、forceUpdate()
但是今天遇到一个问题让我涨了新知识!
项目中使用dva.js轻量级的应用框架,在组件中通过dispatch触发model中数据改变,调用reducers中的函数返回需要改变的数据,model数据确实已经发生改变,在组件中也通过this.porps,正确获取到数据修改前的状态,但是修改之后并没有获取到,写在componentDidUpdata里面也没有正确输出,百度查到说这个props如果是引用数据类型的话,当这个引用数据类型的地址不发生变化时,是不会触发componentWillReceiveProps,有博主使用this.forceUpdate(),功能是实现了,但是这个强制还是不加的好。
还有博主遇到以下问题并通过重新创建一个对象来触发重新渲染
所以我个人认为是浅拷贝导致的问题,应该将引用类型的数据通过深拷贝获得。
我模仿上面博主的方式,也改写了我的代码
setLogInfoData(state, payload) {
let newState = { ...state }
newState.bottomStorsgeResultOne = [...payload.data.arrOne],
newState.bottomStorsgeResultTwo = [...payload.data.arrTwo],
newState.bottomStorsgeResultThree = [...payload.data.arrThree],
newState.bottomStorsgeResultFour = [...payload.data.arrFour]
return newState
},
我以为这样就对了,但是还是没有触发重新渲染,我在组件中要通过props获得bottomStorsgeResultOne,bottomStorsgeResultTwo,bottomStorsgeResultThree,bottomStorsgeResultFour,它们都是数组,一拍脑袋才想起来,不能简单使用三点运算符!!!
比如说:let arr2 = […arr1],三点运算符只能实现外层的深拷贝,也就是当数组里面包含对象的时候,改变数组里面对象的值仍然会影响原数组的值,上面博主获取的visible是原始类型,所以解决了问题,可我要得到的是数组啊!
于是,我又对代码进行了修改,把对象里面的数组深拷贝了一层,然后又深拷贝了对象,这样数组改变就实现了组件重新渲染。
setLogInfoData(state, payload) {
let arrOne = [...payload.data.bottomStorsgeResultOne], arrTwo = [...payload.data.bottomStorsgeResultTwo], arrThree = [...payload.data.bottomStorsgeResultThree], arrFour = [...payload.data.bottomStorsgeResultFour], newState = { ...state }
newState.bottomStorsgeResultOne = [...arrOne],
newState.bottomStorsgeResultTwo = [...arrTwo],
newState.bottomStorsgeResultThree = [...arrThree],
newState.bottomStorsgeResultFour = [...arrFour]
return newState
},
== 方法比较笨,还可以用数组的深拷贝 let arr2 = JSON.parse(JSON.stringify(arr1)) ,大家可以试一试,或者有更好的方法欢迎留言==