【问题标题】:Does useState not call a rerender when working with object states?使用对象状态时 useState 不会调用重新渲染吗?
【发布时间】:2019-09-10 07:30:13
【问题描述】:

我有一个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 会正确更新为新值(在setData 方法调用后调用console.log(data) 会显示这一点)。但是,component 没有 reRenderdata 的新值。

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

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

谢谢。

【问题讨论】:

    标签: reactjs firebase render react-hooks


    【解决方案1】:

    尝试设置有效负载的副本:{...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 上探索此示例。

    【讨论】:

    • 这是正确的,但你应该解释为什么会这样。
    猜你喜欢
    • 2019-06-26
    • 1970-01-01
    • 2020-06-13
    • 2022-06-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2021-09-09
    • 1970-01-01
    相关资源
    最近更新 更多