Обновление родительского состояния в дочернем useEffect с помощью массива зависимостей вызывает цикл - PullRequest
0 голосов
/ 25 апреля 2020

Проблема как описано в заголовке. У меня в родителе есть состояние, которое я хочу обновить у ребенка. Однако передача функции setState в качестве реквизита и ее обновление в дочернем useEffect вызывает al oop. Это происходит независимо от массива зависимостей.

Я полагал, что это происходит потому, что обновление родительского состояния вызывает повторную визуализацию дочернего элемента, обновление зависимой от проп и запуска другой повторной визуализации. Хотя я не уверен, что это правильно.

Если кто-то может объяснить, почему это происходит, и найти правильное решение, я был бы рад.

Кроме того, ниже приведена логика c, которая вызывает это поведение.

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>)
}

1 Ответ

0 голосов
/ 25 апреля 2020

Я бы порекомендовал посмотреть шире и спросить, почему вам нужно обновить состояние родителя значением из состояния ребенка. У вас должен быть один и только один «источник правды» для каждого свойства, плохая практика дублировать свойства в состояниях родителя и ребенка. Поэтому лучше передать state от Parent до Child, а не Child с собственным свойством. Это канонически неуместный способ.

Я полагаю, что я делаю что-то подобное в ситуации выше:

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>)
}
...