React React-Hooks useEffect dependency array

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

React React-Hooks useEffect dependency array

问题

The code you provided raises a question about whether a function that never changes (i.e., a pure function) should be included in the dependency array of a useEffect hook. According to the React documentation, everything used inside the useEffect should generally go into the dependency array. However, there can be exceptions, and in this case, you're passing a callback function (onChange) from the parent to the child component, and it triggers a re-render in the parent.

So, while it's recommended to include all dependencies in the array, if you're certain that the onChange function will never change throughout the component's lifecycle, you can omit it from the dependency array. This can improve performance by preventing unnecessary re-renders caused by changes in the dependency array. However, be cautious and ensure that the onChange function indeed remains constant.

英文:

if a function that never change ( it is pure ) should it go inside the dependency array ?

let say this is my child component :

function ChildComponent({onChange}) {
    const [state, setState] = useState('state')

    useEffect(() => {
    onChange(state)
    }, [state])

    return <h1 onClick={_ => setState('newState')}> something </h1>
}

and this is my Parent component that uses the child

function ParentComponent({addressItems}) {
    const setSomething = something => {
       // push something in browser address bar
       // this cause a reRender in Parent Component because in a higher level we pass the addressItems to ParentComponent as props 
    }

    const handleNameChange = name => {
      setSomething(name)
    }

    return <> <ChildComponent onChange={hanldeNameChange}/> </>

}

this is what do i mean

and note that every time that onChange function runs it cause a reRender in parent component

i have changed this code and move it to the event handler and it works fine but the react.dev docs says that everything that is inside the useEffect should go into the dependency array is this an exception ?

答案1

得分: 0

以下是翻译好的内容:

不确定这个答案是否完整,但我会给出我的理解。
在效果中使用的所有内容严格来说都应该在依赖数组中。React 不知道它是否会更改,因此要求所有变量都在数组中。如果它不更改,它将不会触发该效果。

在你的情况下,我认为这经常会发生,如果将它添加到依赖项中,你可能会得到一个无限运行的效果。

子状态更改 -> 效果运行 -> 回调运行 -> 回调更改父级 -> 
父级重新渲染 -> 函数的新引用 -> 依赖项通过引用更改 -> 使用效果触发...

因此,问题在于依赖关系是按引用进行比较的,如果父级重新渲染,那么回调就有一个新的引用。我认为如果父级重新渲染取决于子状态实际更改,那么这可能不是一个问题。

如果是这样,你可以将回调从依赖项中省略,并依赖于你知道它不会更改这一事实,或者在父组件中,你可以使用 useCallback 来确保函数在重新渲染之间保持相同的引用。

英文:

Not sure how complete this answer is but I'll give my understanding.
Everything that is used in the effect should strictly speaking be in the dependency array. React does not know whether it will change or not so requires that all variables be in the array. And if it does not change it will not trigger the effect.

In your case, and I think this happens often, you will probably get an infinite run of the effect if you add it to deps.

Child state changes -> effect runs -> callback runs -> callback changes parent -> 
parent rerenders -> new reference for function -> deps changes by reference -> use effect triggers ...

So the issue is dependencies are compared by reference and if the parent rerenders then the callback has a new reference.
I think its possible if the parent rerender is dependant on the child state actually changing that this will not be an issue.

If it is, you can either omit the callback from the deps and rely on the fact you know it does not change, or in the parent component, you can use useCallback to ensure the function keeps the same reference between rerenders.

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

发表评论

匿名网友

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

确定