为什么我在setState时没有更新我的React Hook?

时间:2019-10-11 16:55:24

标签: javascript reactjs typescript react-hooks

我正在使用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类型表示歉意,但在此处包括了它们,以便您可以看到状态的预期形状。

由于更改嵌套很深,它是否没有更新?是否有办法使它起作用,还是我需要以某种方式将更改后的状态拉到自己的状态?

1 个答案:

答案 0 :(得分:5)

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);