使用对象状态时,useState不会调用rerender吗?

问题描述 投票:1回答:1

我有一个firebase项目与firestore database document看起来像这样。

document-id => 
    item1 => {detail: "value", title: "value", image: "value}
    item2 => {detail: "value", title: "value", image: "value}
    ...

我的React component渲染它看起来像这样:

const [data, setData] = useState({});

useEffect(() => {
  firebase.getDocument("path-to-document").then(section => {
    if (section) {
      setPanels(section.data());
    }
  });
}, []);

const handleChange = (id, data) => {
  const payload = data;
  payload[id] = { ...panels[id], ...data };
  setData(payload);
}

return (<div>
  {Object.keys(data).map((key) => <Card
    data={data[key]}
    onChange={handleChange} />)}
</div>);

我从中删除了额外的代码,但Card组件简单地设置了各个对象的布局。在更改时,它正确调用handleChange函数,并且data State正确更新为新值(在console.log(data)方法调用显示此之后调用setData)。然而,component没有reRenderdata的新值。

有没有办法强制组件重新渲染?我在网上其他地方发现,如果使用与当前相同的数据调用setData,那么React将从退回中“保释”,即不会进行实际更改。

或者相反,有另一种方法来处理这种交互,并让Card组件处理数据的持久性?

谢谢。

reactjs firebase render react-hooks
1个回答
3
投票

尝试设置有效负载的副本:{...payload}

const handleChange = (id, data) => {
  const payload = data;
  payload[id] = { ...panels[id], ...data };
  setData({...payload});
}

因为您没有更改状态,您的应用程序不会React并重新呈现。

在React Docs上查看Functional Updates

const handleChange = (id, data) => {
  const payload = data;
  payload[id] = { ...panels[id], ...data };
  setData(prevPayload => {
      console.log(prevPayload === payload)            // true
      return payload                                  // No Re-Render

      // console.log(prevPayload === { ... payload }) // false
      // return { ... payload }                       // Re-render
  );
}

codesandbox上探索这个例子。

© www.soinside.com 2019 - 2024. All rights reserved.