使用备忘录反应嵌套对象状态

React Nested Object State Using Memo

我将 props 传递给函数组件:

const [accountForm, setAccountForm] = useState({})

const syncForm = (subForm, name) => {
  const form = {...accountForm, [name]: subForm}
  setAccountForm(form)
}

<>
  <ComponentA handler={syncForm} form={accountForm.objA} />
  <ComponentB handler={syncForm} form={accountForm.objB} />
  <ComponentC handler={syncForm} form={accountForm.objC} />
</>

组件(A、B 和 C)的编写方式类似:

const ComponentA = ({form, handler}) => {
  const handler = () {
    handler()
  }

  return (
    <Form onChange={handler}/>
  )
}

const areEqual = (n, p) => {
  const pForm = p.form;
  const nForm = n.form;
  const equal = pForm === nForm;
  return equal;
}

export default React.memo(ComponentA, areEqual)

我使用备忘录是因为组件 A、B 和 C 具有相同的父级,但我只想在它们的子表单更改时重新呈现 A、B 或 C,所以我不想验证 运行 在其他表格上。

当我填写表格 A 时,所有值都已正确存储。当我填写不同的表单(例如 B 或 C)时,表单 A 恢复为空对象 {}。

但是,如果我将状态更改为 3 个对象而不是嵌套对象,它会起作用:

const [objA, setObjA] = useState({});
const [objB, setObjB] = useState({});
const [objC, setObjC] = useState({});

<>
  <ComponentA form={objA} />
  <ComponentB form={objB} />
  <ComponentC form={objC} />
</>

为什么嵌套对象方法不起作用?

这似乎是对 accountForm 状态的陈旧封闭。看起来 memo HOC 和 areEqual 函数阻止子组件重新呈现和接收具有更新状态的 handler 回调。

使用功能状态更新从任何先前状态正确更新,而不是任何回调范围内关闭的状态。

const syncForm = (subForm, name) => {
  setAccountForm(form => ({
    ...form,
    [name]: subForm
  }));
}