场景:网络请求得到数据后,赋值给本地(state)的一个变量
state = { lanesData: [] }
static getDerivedStateFromProps(nextProps, prevState) {
if (!isEmpty(nextProps.mallDecorationDetail)) {
return { lanesData: nextProps.mallDecorationDetail }
}
return null;
}
遇到的问题:props与受控组件内部状态state控制受冲突
请求数据返回后,确实赋值给了lanesData变量,但后续对state.lanesDate进行setState时,state又被赋值为了props.mallDecorationDetail 的值
分析:
因为props和state的改变都会触发static getDerivedStateFromProps,后续的setState操作是生效了,但是state的改变触发了getDerivedStateFromProps生命周期,lanesDate又被赋值为props.mallDecorationDetail 的值,导致lanesDate没有更新为我们想要的值,看起来像setState失效一样。
解决:加上本地变量是否为空的初始判断,只有在state为空并且props.mallDecorationDetail不为空时,才派生lanesData
static getDerivedStateFromProps(nextProps, prevState) {
if (isEmpty(prevState.lanesData) &&!isEmpty(nextProps.mallDecorationDetail)) {
return { lanesData: nextProps.mallDecorationDetail }
}
return null;
}
又遇到了问题:
如果想对lanesData setState为空,会发现lanesData又被赋值为nextProps.mallDecorationDetail的值。因为判断条件(isEmpty(prevState.lanesData) &&!isEmpty(nextProps.mallDecorationDetail))成立了,又被赋值为props.mallDecorationDetail的值
解决:初始值设置为一个不一样的类型,确保后续的setState操作不会和这个类型的值相等,这样就不会重新被赋值。
state = { lanesData: undefined }
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.lanesData === undefined &&!isEmpty(nextProps.mallDecorationDetail)) {
return { lanesData: nextProps.mallDecorationDetail }
}
return null;
}
改进:
将初始值设置为一个不一样的类型,而且还要确保后续的setState操作不会和这个类型的值相等,这显然不是一个好主意。可以再添加一个变量来控制是否为第一次赋值
state = { init: true}
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.init &&!isEmpty(nextProps.mallDecorationDetail)) {
return {
lanesData: nextProps.mallDecorationDetail,
Init: false
}
}
return null;
}