1
votes

Say I have this component, with the following hook:

function SomeComponent(props) {
useEffect(
    () => {
        //....code
        if (props.propOne === ....) { .... }
        // ...code
        if (props.propTwo === ....) { .... }
    }, 
    [props.propOne]
)

return <Something />

}

The above hook will run

  • once on the first time the component code gets executed
  • every time the value of props.propOne changes

Notice however that the hook callback also makes a reference to pros.propTwo, without actually having it passed to the dependencies array.

While props.propTwo will never factor in whether the hooks gets re-executed, what happens to the value of it that the hook callback references inside its body?

for example

  • During initial component rendering props.propOne === A and props.propTwo === B
  • The hook gets executed and references values A and B
  • During a subsequent rendering props.propOne === C and props.propTwo === D
  • The hook gets re-executed, since props.propOne changed. It references value C for the props.propOne but what does it reference for the props.propTwo value? B or D?

Does the hook reference values based on the closure created on component execution or does React do some voodoo where it only keeps the updated value for values passed to the dependencies array?

From the docs:

The array of dependencies is not passed as arguments to the callback. Conceptually, though, that’s what they represent: every value referenced inside the callback should also appear in the dependencies array.

UPDATE:

After asking the question I fell unto this article, by Dan Abramov:

https://overreacted.io/a-complete-guide-to-useeffect/

I suggest everyone to read it.

1
Surely the simple solution is to include props.propTwo in the dependencies then, if as you say 'While props.propTwo will never factor in whether the hooks gets re-executed...' ? - rrd
Yes, but this was not the point of the question. - Dimitris Karagiannis

1 Answers

2
votes

React hooks rely heavily on closures to make use of values. The values that are referenced within the hook will be the values that were present in the closure of useEffect when it was last called.

For instance, in your example if props.propOne is changed and in the subsequent render props.propTwo is changed, the value of props.propTwo inside the useEffect callback will the previous value since useEffect is not executed when props.propTwo changes.

If however, you are updating props.propOne and props.propTwo together, then the value inside useEffect hook will be the updated one.

Considering your case where the props.propOne and props.propTwo are changed together and trigger a render, the value of props.propTwo will be D inside useEffect callback