首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从多个子组件同时更新父状态

从多个子组件同时更新父状态
EN

Stack Overflow用户
提问于 2021-06-02 03:15:49
回答 2查看 1.5K关注 0票数 5

我有一个父组件,它有自己的状态,并且也在子组件之间共享。

在我的子组件中,我有一个表单,对于数据,我创建了一个本地状态。让我们调用这个子组件。

在我的父组件中,有一个按钮可以将数据从我的子组件的本地状态更新到我的父级状态。这是我通过从父母传递给孩子的标志来完成的。

另外,我的父母两次呈现相同的子程序,最后代码如下所示:

代码语言:javascript
运行
复制
const parent = () => {
  const [parentState, setParentState] = useState(null);
  const [submitSignal, setSubmitSignal] = useState(false);

  const handleSave = () => {
    setSubmitSignal(true);
  }

  return (
    <div>
      <div onClick={handleSave}>
        Save Data
      </div>

      <Child
        pos={0}
        key={0}
        parentState={parentState}
        submitSignal={submitSignal}
        setParentState={setParentState}
      />

      <Child
        pos={1}
        key={1}
        parentState={parentState}
        submitSignal={submitSignal}
        setParentState={setParentState}
      />
    </div>
  )
}

const Child = (props) => {
  const [childState, setChildState] = useState(null);

  React.useEffect(() => {
    const { pos, submitSignal, parentState, setParentState } = props;
    if (submitSignal) {
      setParentState(...parentState, ...childState);
    }
  }, [props.submitSignal])

  return (
    <div>
      // A large form which multiple fields
    </div>
  )
}

现在发生的事情是,只要我使父组件中的submitSignal变为真,两个子组件同时接收它,并尝试更新父组件的状态。这是一种竞争条件,在此情况下,子0更新数据,但在父状态更新之前,Child 1还会更新父状态,从而覆盖/删除Child 0添加的内容。

请帮我解决这个问题。

P.S:,我之所以使用这个结构,是因为在我的孩子里,我有一个非常大的表单,相同的表单被使用了两次。

EN

回答 2

Stack Overflow用户

发布于 2021-07-26 14:02:53

您必须使用回调函数,而不是直接设置父状态。这样,您将在重写状态时得到更新的前一状态。

代码语言:javascript
运行
复制
    if (submitSignal) {
      setParentState((pstate)=>{
         return {...pstate,...childstate}
      });
    }

https://stackoverflow.com/a/68531170/5707801

票数 1
EN

Stack Overflow用户

发布于 2021-07-27 10:02:49

我明白为什么你会困惑,这实际上是完全按照预期的工作。

在我继续之前:注意:

  • 本节 -阅读‘呈现’和‘更新’的定义。 总之:“update”是执行FC(Fonctional )主体,“render”是更新,包括它们的以下效果。
  • 从效果调用状态钩子(如useEffect或useLayoutEffect)将导致对另一个呈现的调度作出反应。见示例
  • 从FC主体调用状态钩子将导致对另一次更新调用的响应。见示例

有关更多细节,请阅读我的文章如何反应-钩子-工作。它将帮助您更好地理解功能组件、生命周期和挂钩。

关于你的案子:

关于您的具体问题:遵循代码沙箱,就像您的代码有一些日志一样。

订单

阶段顺序:

  • 父更新
  • 儿童最新情况*2
  • 儿童效应*2
  • 亲本效应

日志

  • 在挂载上,父更新,然后两个子更新。然后激发子效应,然后触发父效应。
  • 调用已发生的=> handleSave,这将设置状态,在FC主体中,因此react将安排另一个更新。
  • 将执行更新(记录“父”和“子”*2)。submitSignal设置为true。
  • 现在我们进入了效果阶段:'submitSignal‘被更新了,因此两个子级都在效果阶段=>中填充setState (在父级上)--另一个父级呈现周期被调度。(与称为setState的两个不同的子级无关,只有一个呈现将通过react调度)。
  • 父级(和子代)用更新的值进行更新。

这里没有任何赛车条件,如果1000个孩子请求更新(例如通过setstate ),那么react就不在乎了。因为所有更新请求都处于相同的阶段,因此将只调度一个呈现。

如果您很难理解它,我建议您阅读我的文章“如何反应-钩子-工作”,文章中有简单而复杂的示例来演示这些行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67798460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档