简体   繁体   English

从多个子组件更新父组件 state 未考虑更新的 state 值

[英]Updating Parent component state from multiple child components not taking updated state value into account

I have a question related to react js.我有一个与 React js 相关的问题。

I have a scenario where we have a state in the parent component.我有一个场景,我们在父组件中有一个 state。 It has to be updated by child component.它必须由子组件更新。 So that, based on the state value, I'll do something else in the parent component.因此,基于 state 值,我将在父组件中执行其他操作。

But, If I render multiple child components, the parent's state is getting updated only once.但是,如果我渲染多个子组件,则父组件的 state 只会更新一次。

Could you please help me understand why the state is updating only once and what would be the possible workaround.您能否帮我理解为什么 state 只更新一次以及可能的解决方法是什么。

Below is the code sandbox link with the example.下面是示例的代码沙箱链接。

https://codesandbox.io/s/heuristic-cori-8793u?file=/src/App.js https://codesandbox.io/s/heuristic-cori-8793u?file=/src/App.js

Thanks.谢谢。

Refer to the doc:参考文档:

Unlike the setState method found in class components, useState does not automatically merge update objects.与 class 组件中的 setState 方法不同,useState 不会自动合并更新对象。

doc Link .文档链接
So you can't pass the old state in a setState() like setCount(count + 1);所以你不能像setCount(count + 1);这样在setState()中传递旧的 state; . . Because React will "change" your count value during a re-render and in your case you are calling setCount() many time before React have the time to render again.因为 React 将在重新渲染期间“更改”您的count数值,并且在您的情况下,您在 React 有时间再次渲染之前多次调用setCount()
And this is also why your console.log(count) displays the previous value.这也是为什么你的console.log(count)显示之前的值。
One solution is this syntax setState(prevState=> prevState+1) .一种解决方案是这种语法setState(prevState=> prevState+1)
try this:尝试这个:

import "./styles.css";
import { useEffect, useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  const updateCounter = () => {
    setCount((prevCount) => prevCount + 1);
  
  };

  useEffect(() => {
    console.log("Do Something Based On Count Value.");
  }, [count]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox {count}</h1>
      <ChildApp onLoad={updateCounter} />
      <ChildApp onLoad={updateCounter} />
      <ChildApp onLoad={updateCounter} />
    </div>
  );
}

export function ChildApp({ onLoad }) {
  console.log("Child Loaded");
  useEffect(() => {
    onLoad();
  }, []);
  return (
    <div className="App">
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

codeSanBox codeSanBox

The problem is caused by the fact that updateCounter has closed over the value of count , so when you call it twice with two child components the 'old' value of count is used both times.问题是由于updateCounter已经关闭了count的值,因此当您使用两个子组件调用它两次时,两次都使用count的“旧”值。 You can avoid it by using the 'update' form of useState .您可以通过使用useState的“更新”形式来避免它。 This ensures that you will increment the 'current' value of count :这可确保您增加count的“当前”值:

const updateCounter = (num) => {
  setCount(c => c + 1);
  console.log(count);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM