使用对象状态时,useState是否不调用重新渲染?

时间:2019-04-20 08:43:16

标签: reactjs firebase render react-hooks

我有一个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不会reRender带有data的新值。

是否有某种方法可以强制重新渲染组件?我在网上其他地方发现,如果调用setData的数据与当前使用的数据相同,即React会“重投”,即不进行任何实际更改。

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

谢谢。

1 个答案:

答案 0 :(得分:3)

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

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

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

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上浏览此示例。