简体   繁体   中英

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. However, passing the setState function as a prop and updating it in the child's useEffect causes a loop. 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. 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. 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. 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>)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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