简体   繁体   English

使用依赖数组更新子 useEffect 中的父 state 会导致循环

[英]Updating parent state in child useEffect with dependency array causes loop

Problem is as described in title.问题如标题所述。 I have a state in my Parent that I want to update in a child.我的父母中有一个 state,我想在孩子身上更新。 However, passing the setState function as a prop and updating it in the child's useEffect causes a loop.但是,将 setState function 作为道具传递并在孩子的 useEffect 中更新它会导致循环。 This happens irregardless of the dependency array.无论依赖数组如何,都会发生这种情况。

I figured this happens because updating the parent state causes a re-render of the child, updating the depended upon prop and triggering another re-render.我认为发生这种情况是因为更新父 state 会导致子重新渲染,更新依赖的道具并触发另一个重新渲染。 Not sure if this is correct, though.不过,不确定这是否正确。

If anyone can explain why this happens and a proper solution, I'd be glad.如果有人可以解释为什么会发生这种情况并提供适当的解决方案,我会很高兴。

Also, below is the logic that causes this behavior.此外,以下是导致此行为的逻辑。

export const Parent = () {
    const [state, setState] = useState({something})

    switch(thing) {
       return <Child onNext={someFunction} setSettings={setState}/>
    }
}

const Child = (props) => {
    { onNext, setSettings } = props
    const [childState, setChildState] = useState({something})

    useEffect(
        () => {
            setSettings(childState)
        }, [childState])

    return(<h1>foobar</h1>)
}

I'd recommend looking broader and ask why you need to update parent's state with the value from child's state.我建议您扩大范围,并询问为什么您需要使用孩子的 state 的值更新父母的 state。 You should have one and only have "source of truth" for each property, it is bad practice to duplicate property in parent's and child's states.对于每个属性,您应该有一个并且只有一个“事实来源”,在父母和孩子的状态下复制财产是不好的做法。 Therefore, it's better to pass state from Parent down to Child rather than Child having its own property.因此,最好将stateParent传递给Child ,而不是Child拥有自己的属性。 It is a canonically inappropriate way.这是一种典型的不恰当方式。

I suppose doing smth like this in the situation above:我想在上述情况下这样做:

export const Parent = () {
    const [state, setState] = useState({something})
    const [stateForChild, setStateForChild] = useState({somethingAnother})

    switch(thing) {
       return <Child onNext={someFunction} setSettings={setState} stateForChild={stateForChild} setStateForChild={setStateForChild}/>
    }
}

const Child = (props) => {
    { onNext, setSettings, stateForChild, setStateForChild } = props

    // use stateForChild and setStateForChild

    return(<h1>foobar</h1>)
}

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

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