英文:
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 <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>
}
答案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(() => {
props.setErrors((previousErrors)=> {...previousErrors, [props.identifier]:0});
}, []);
return <React.Component>
</React.Component>
}
答案2
得分: 2
你可以将一个函数传递给 setErrors
,以根据先前的状态更新值。
props.setErrors(prev => ({...prev, [props.identifier]: 0}));
请参阅 useState
中 set
函数的文档:
如果你将一个函数作为 nextState 传递,它将被视为一个更新函数。它必须是纯函数,只接受待处理的状态作为其唯一参数,并应返回下一个状态。React 将把你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过将所有排队的更新应用于先前的状态来计算下一个状态。
英文:
You can pass a function to setErrors
to update the value given the previous state.
props.setErrors(prev => ({...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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论