3

everyone! Imagine, I have a component SomeComponent. Every time 'b' value changes, useEffect is triggering despite 'b is not in its dependencies

const SomeComponent = () => {
  const a = [1, 2, 3] //just an example of dependency. In real life it will be a changing value
  const b = useSelector(someValueSelector)

  useEffect(() => {
    //do some staff
  }, [a])
}

Is there any way to store reference to 'a' array inside of SomeComponent? The only way I know is to create a wrapper component and pass

a = useMemo(() => [1, 2, 3], [])

as a props to

<SomeComponent a={a} />

2 Answers 2

1

The issue here is that on every re-render a's reference changes and hence the useEffect is triggered again

You can make use of useMemo inside SomeComponent to assign a memoized value to a

const SomeComponent = () => {
  const a = useMemo(() => [1, 2, 3], []); 
  const b = useSelector(someValueSelector)

  useEffect(() => {
    //do some staff
  }, [a])
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! Is there a possibility to combine this with a function that depends on some state (redux for example)?
Could you elaborate on it please, so that I can update my post with more finer details. As of now I am only working with what you have provided
Oh, I found a solution, typing to you )) Thank you again!
I am guessing that has to do with calling the function inside useMemo with the appropriate dependency. Good that your issue is resolved :-) Glad to have helped
0

As you may have gathered, but to be explicit for any future readers, this is due to object equality in JavaScript. Since objects are compared by reference, {} === {} evaluates to false.

Depending on your use case, you can work around this in the following ways:

  1. If the values are static and not dependent on props, define a in the same scope as the component. This removes the need to declare it as a dependency for the useEffect routine:

    const a = [1, 2, 3]
    const SomeComponent = () => {
      useEffect(() => {
        // do something with `a`
      }, [])
    }
    
  2. If the value is dynamic but changes should not cause the component to re-render, use a ref. Changing the value of the ref will not prompt React to re-render the component and the same object will be returned from useRef() on each render:
    const SomeComponent = () => {
      const ref = useRef([1, 2, 3])
      useEffect(() => {
        // do something with ref.current
      }, [ref])
    }
    
  3. Finally, if the value of a is dynamic or dependent on props that may change over time, use useMemo. Be aware that useMemo is not a semantic guarantee—React may opt to eject stored values to free memory, and so it should only be used as a performance optimization:
    const SomeComponent = () => {
      const a = useMemo(() => [1, 2, 3], [])
      useEffect(() => {
        // do something with a
      }, [a])
    }
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.