首页 > 解决方案 > 为什么当我设置状态时我的 React Hook 没有更新?

问题描述

我正在使用 react useState,其中状态是具有一些嵌套属性的对象。当我调用setState它时,我没有看到重新渲染或状态正在更新。我假设反应看到新状态等于旧状态,因此不会发生更新。所以,我已经尝试先克隆状态,但仍然没有看到任何更新。

我怎样才能让这个函数导致状态更新?

export type TermEditorStateRecord = {
  term: SolrTermType;
  state: SolrTermEditorRecordState;
  classifications: { [key: string]: string };
};

export type TermEditorStateRecordMap = {
  [phrase: string]: TermEditorStateRecord;
};

const [records, setRecords] = useState({});

const setRecordClassification = (label, key, value) => {
  const cloned = new Object(records) as TermEditorStateRecordMap;
  cloned[label].classifications[key] = value;
  setRecords(cloned);
};

对于 TypeScript 类型,我深表歉意,但我已将它们包含在此处,以便您可以看到预期的状态形状。

是不是因为变化嵌套太深而没有更新?有没有办法让它工作,还是我需要以某种方式将改变的状态拉到它自己的状态?

标签: javascriptreactjstypescriptreact-hooks

解决方案


new Object不会进行深层复制,因此因为setRecords它是同一个实例并且不会触发重新渲染,

const obj = {
  a: {
    b: "b"
  }
};

const copy = new Object(obj);

copy["c"] = "c";

console.log(obj);

您需要手动更新嵌套属性:

const setRecordClassification = (label, key, value) => {
  setRecords(record => ({
    ...record,
    [label]: {
      ...record[label],
      classifications: {
        ...record[label].classifications,
        [key]: value
      }
    }
  }));
};

或创建一个副本,使用:

const cloned = JSON.parse(JSON.stringify(record));
cloned[label].classifications[key] = value;
setRecords(cloned);

推荐阅读