Reactjs React/Redux:componentDidUpdate未一致触发
我的道具中有嵌套数组,用户可以通过拖放列来重新排列第二级数组。我(使用redux)创建getState外部数组的浅层副本,重新排序(通过基于索引重新分配数组对象),并将新数组返回到状态(使用我的reducer中的spread操作符)。但是,如果此排序是我在页面加载后做的第一件事,则不会调用Reactjs React/Redux:componentDidUpdate未一致触发,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我的道具中有嵌套数组,用户可以通过拖放列来重新排列第二级数组。我(使用redux)创建getState外部数组的浅层副本,重新排序(通过基于索引重新分配数组对象),并将新数组返回到状态(使用我的reducer中的spread操作符)。但是,如果此排序是我在页面加载后做的第一件事,则不会调用componentdiddupdate。如果我采取其他更新道具/状态的操作,然后尝试重新订购,订购工作正常,并调用componentdiddupdate 在前一种情况下,在页面加载/刷新之后,排序是我尝试做的第
componentdiddupdate
。如果我采取其他更新道具/状态的操作,然后尝试重新订购,订购工作正常,并调用componentdiddupdate
在前一种情况下,在页面加载/刷新之后,排序是我尝试做的第一件事,渲染函数被命中(使用正确重新排序的道具),但DOM从未更新,大概是因为redux无法识别状态更改
它看起来就像其他一些道具发生了变化(即使与阵列无关)“唤醒”redux或connect
并允许它识别变化
在这里,我复制、分派并发布reducer中的更新状态:
在actionCreator方法中:
...
const newProjects = getState().tracker.projects.slice().map(p => {
if (p.innerArray) {
const from = p.innerArray[draggedId-1];
const to = p.innerArray[droppedId-1];
p.innerArray[draggedId - 1] = { ...to, order: draggedId };
p.innerArray[droppedId - 1] = { ...from, order: droppedId };
}
return p;
})
dispatch({ type: 'RECEIVE_FIELD_UPDATE', projects: newProjects, message: "Sorted" });
减速器:
case 'RECEIVE_FIELD_UPDATE':
return {
...state,
projects: action.projects,
message: action.message
}
正如您所看到的,我并没有在减速器中改变状态,也没有做其他反模式的事情(据我所知)
FWIW,无论是否点击componentdiddupdate
,message属性上的“Sorted”值似乎都能通过(我有一个弹出消息以确认的模式)
任何指针或相关文档都会有帮助;我一直在阅读我能找到的所有东西,包括其他StackOverflow帖子,但都没有用
更新
解决了这个问题,它确实与redux有关,而不是因为我的预期,如果有兴趣,请阅读下面的内容。当以数组格式更新reducer中的状态时,我必须再次传播状态,以便发生更新并防止变异
case 'RECEIVE_FIELD_UPDATE':
return {
...state,
projects: ...state, ...action.projects,
message: action.message
}
或者
取决于格式。
希望有帮助 我发现了这一点,但按照惯例,我找错了地方 问题是,我对页面加载的条件检查防止重新加载已存储的数据,这会阻止触发任何调度。当我在reducer中查看时,项目的子数组在拖动后是相同的,因为状态之前还没有连接。我原以为硬刷新会导致完全重新加载,但显然我需要阅读更多关于redux如何存储数据以及如何刷新数据的内容
无论如何,修复此条件以便在页面加载时获得新数据修复了此问题,并且
componentdiddupdate
现在被一致触发。谢谢,但项目不是顶级状态,它只是状态对象的一个属性,因此上述操作将引发错误。我可以看到混乱,虽然我没有深入到状态树与我的职位。由于没有添加或删除任何项目,因此将国家项目扩展到行动项目的结果与以前相同。
case 'RECEIVE_FIELD_UPDATE':
return {
...state,
projects: [...state, ...action.projects],
message: action.message
}