由于点击保存后再次将 store 状态传递给 item,需要监听 Item 中的 props 变化并再次设置状态以触发重新渲染。
因此,第一步是找出我们想要监控哪个值的变化。从代码中可以看出status是最佳候选。
Item.js
// not the final solution
// monitor props status change, set the state again and trigger rerender
useEffect(() => {
setState({ ...state, ...props });
}, [props.status]);
但是,如果我们使用props.status 来触发重新渲染,就会有一个问题需要解决。
例如
当你第一次点击item 2的保存时,item status从open -> lock,Item重新渲染。没问题!
但是当您将item 2的下拉框从lock更改为open并再次点击save时,Item将不会重新渲染。
由于item 2更新后的店铺状态依旧标记为lock,之前的状态也是lock,没有任何变化从反应的角度来看。
您可以查看codesandbox 来模拟问题。
为了解决这个问题,我们需要引入额外的属性来监控它的变化以进行重新渲染。我使用updatedAt 为每次更新生成时间,让我们知道值存在差异并为我们触发重新渲染。
modal.js
items: [
{ id: 1212, title: "Watch mojos", subtitle: "", status: "open", updatedAt: null },
{ id: 1213, title: "Drink cheetos", subtitle: "", status: "open", updatedAt: null },
{ id: 1214, title: "Eat frodos", subtitle: "", status: "lock", updatedAt: null }
]
saveItem: action((state, payload) => {
console.log(payload);
state.items = state.items.map((d) => {
if (d.id === payload.id) {
d.status = "lock";
d.updatedAt = new Date(); // assign new date on each update
}
return d;
});
})
Item.js
useEffect(() => {
setState({ ...state, ...props });
}, [props.updatedAt]); // monitor update date change instead of status change
这里是workable codesandbox