state更新,视图不更新,如何解决?
初学taro框架,真的遇到了很多很多的问题。之前也只是跑了一遍react官网的入门教程,就直接上手react技术栈了。
今天写一个demo,在使用redux更新state的时候,就遇到了视图死活不更新的情况。点击事件进入reducer执行后,视图不更新,但是拖拽视图上的swiper后(相当于再次触发render()方法),视图才更新。
后来查了很多博客,以及自己的一些试验,得出结论:state的确更新了,但是是在reducer方法return之前就更新了!
结果就是return的state与redux管理的state是同一个,那么render方法自然不会触发!
reducer传入的state其实是引用
这是我定义的state,因为是第一次写,而且是把之前写的原生小程序拿来改成taro,所以state很冗杂
const INITIAL_STATE = {
batteryMomList:[
{
name: ''1,
batteryList: [
0, 0, { id: 2, quantity: 100 }, { id: 3, quantity: 100 },
0, 0
]
},
{
name: '2',
batteryList: [
{ id: 5, quantity: 100 }, 0, { id: 6, quantity: 100 }, { id: 7, quantity: 85 },
0, { id: 8, quantity: 20 }
]
},
{
name: '3,
batteryList: [
{ id: 9, quantity: 40 }, 0, { id: 11, quantity: 100 }, { id: 12, quantity: 8 },
{ id: 13, quantity: 100 }, { id: 14, quantity: 100 }
]
},
],
currentTab:0, //当前滚动到的tab
currBatMomIndex:0, //记录当前滑动到哪个下标
borrowedList:[
{ id: 1, quantity: 100 }, { id: 4, quantity: 50 }
]
}
最开始我用的let stateCopy = {...state}
来操作,但是后来发现,不管是{...state}
还是Object.assign()
都不行,这两个语句其实都是浅拷贝。比如我的batteryMomList数组,拷贝后拿到的仍然只是引用。在reducer中对其进行操作,那么必然会直接修改到state!
再来看看这串代码
case CAGCU:
let currentTab = state.currentTab
currentTab = (currentTab + 1) % 2
return {
...state,
currentTab: currentTab
}
case CAGCUM:
return {
...state,
currBatMomIndex: action.data
}
我代码中currentTab和currBatMomIndex两个键对应的都是数值,这种情下,let currentTab = = state.currentTab
获取的就不是某个引用,而是真的某个数值。所以操作currentTab不会直接改变state中的值
所以,一旦面对的是对象或者数组这种数据类型,必须深拷贝一份在reducer中进行操作!
const borListTemp = JSON.parse(JSON.stringify(state.borrowedList))
taro官方github的issue回答中,推荐这条语句进行深拷贝
还有一个大小不小的坑
reducer中的处理,在我的demo中必须写在case里面,如果是下面这种方式将case中的语句抽出来到一个函数里面,就不行。可能是我对js的理解还达不到,不知道这种方式问题出现在哪里
funcation XXX (state) {
...
return {
...state,
XXX:xxxx
}
}
case 'type':
XXX(state)