数据写入在React中使用useEffect时的冲突。

huangapple go评论114阅读模式
英文:

Conflicts between data write with useEffect in React

问题

我正在尝试从子组件初始化父组件中的数组。我目前有以下解决方案,但是两个 useEffect 调用会互相覆盖,errors 的输出是"{1:0}",而我希望它是"{1:0, 2:0}"。

我不想在父组件中初始化 errors,因为我需要多次编写相同的初始化代码(我希望只附加新的子组件结构,而错误数组应该更改)。这可行吗?

谢谢。

Parent.js:

export default function Parent(props){
   const [errors, setErrors] = React.useState({});
   return (
     <React.Component>
       <Child errors={errors} setErrors={setErrors} identifier="1"/>
       <Child errors={errors} setErrors={setErrors} identifier="2"/>
       {JSON.stringify(errors)}
     </React.Component>
   );
}

Child.js:

export default function Child(props){
    useEffect(() => {
        props.setErrors({...props.errors, [props.identifier]:0});
    }, []);
   return <React.Component></React.Component>;
}
英文:

I'm trying to initialize an array in a parent structure from its children. I currently have the solution below, however the two useEffect calls overwrite each other, and the output of errors is "{"2":0}", where I want it to be "{"1":0, "2":0}.

I don't want to initialize errors in the Parent structure as I would need to write multiple twice the same code for initialization (I optimally would only append the new child structures and the error array should be changed). Is it possible to do?

Thanks.

Parent.js:

export default function Parent(props){
   const [errors, setErrors] = React.useState({});
   return &lt;React.Component&gt;
           &lt;Child errors=errors setErrors=setErrors identifier=&quot;1&quot;/&gt;
           &lt;Child errors=errors setErrors=setErrors identifier=&quot;2&quot;/&gt;
          {JSON.stringify(errors)}
          &lt;/React.Component&gt;
}

Child.js:

export default function Child(props){
    useEffect(() =&gt; {
        props.setErrors({...props.errors, [props.identifier]:0});
    }, []);
   return &lt;React.Component&gt;
          &lt;/React.Component&gt;
}

答案1

得分: 2

你应该在这种情况下使用回调来设置状态:

Child.js:

export default function Child(props){
    useEffect(() => {
        props.setErrors((previousErrors) => ({...previousErrors, [props.identifier]:0}));
    }, []);
   return <React.Component>
          </React.Component>
}
英文:

You should use the callback for setting the state in this case:

Child.js:

export default function Child(props){
    useEffect(() =&gt; {
        props.setErrors((previousErrors)=&gt; {...previousErrors, [props.identifier]:0});
    }, []);
   return &lt;React.Component&gt;
          &lt;/React.Component&gt;
}

答案2

得分: 2

你可以将一个函数传递给 setErrors,以根据先前的状态更新值。

props.setErrors(prev => ({...prev, [props.identifier]: 0}));

请参阅 useStateset 函数的文档

如果你将一个函数作为 nextState 传递,它将被视为一个更新函数。它必须是纯函数,只接受待处理的状态作为其唯一参数,并应返回下一个状态。React 将把你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过将所有排队的更新应用于先前的状态来计算下一个状态。

英文:

You can pass a function to setErrors to update the value given the previous state.

props.setErrors(prev =&gt; ({...prev, [props.identifier]: 0}));

See the documentation for set functions from useState:

> If you pass a function as nextState, it will be treated as an updater function. It must be pure, should take the pending state as its only argument, and should return the next state. React will put your updater function in a queue and re-render your component. During the next render, React will calculate the next state by applying all of the queued updaters to the previous state.

huangapple
  • 本文由 发表于 2023年8月5日 01:19:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838000.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定