当全局状态被修改时,react easy-peasy 组件不会重新渲染

react easy-peasy component is not rerendered when the global state is modified

我是新手,这可能是一个相当简单的问题。我正在使用 easy-peasy 进行状态管理,并且我有一个更新全局状态的操作,但即使在更新全局状态后组件也不会重新呈现。 这是代码框 link。在此示例中,当单击保存按钮时,我将记录更改为“锁定”状态,这应该使其可编辑。 https://codesandbox.io/s/reactjs-playground-forked-sbbh6?file=/src/App.js

当你在点击保存后再次将商店状态传递给项目时,你需要在Item中监听道具变化并再次设置状态以触发重新渲染。

因此,第一步是找出我们要监视哪个值的变化。从代码中可以看出,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触发重新渲染,则有一个问题需要解决。

例如

当您第一次单击 项目 2 上的保存时 item statusopen -> lock 更改,Item 重新渲染。没问题!.

但是当您将 项目 2 的下拉框从 lock 更改为 open 并再次单击 save 时,Item 不会重新渲染。

由于 item 2 的更新商店状态仍然标记为 lock,之前的状态也是 lock,react的观点完全没有变化

您可以检查此 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