useEffect Hook Not Firing After State Change

lsimonetti

I have two sibling components that share state via context in react. The shared state between the components is an array.

If I update arr state in one component, I want the other component to listen for that update and do something accordingly. When I use useEffect in the second component, I listen for changes in the arr state variable.

For example:

// App Component -------
const App = props => {
 const { arr, setArr } = useContext(GlobalContext)

 const handleChange = () => {
   const newArr = arr
   [10, 20, 30, 40].map(v => {
     newArr.push(v)
     setArr(newArr)
   })

  return (...)
}

// App2 (Sibling) Component 
const App2 = props => {
  const { arr, setArr } = useContext(GlobalContext)
  const [localArr, setLocalArr] = useState(0)

  useEffect(
    () => {
      updateLocalState()
    },
    // fire if "arr" gets updated
    [arr]
  )

  const updateLocalState = () => {
    setLocalArr(localArr + 1)
  }

  return (...)
}

The useEffect hook is only fired on the initial render, though the state of arr updates.

I know that declaring a new variable const newArr = arr to my state variable is a reference, so newArr.push(v) is technically a state mutation. However, the state still updates, no warning is thrown, and useEffect does nothing.

Why does useEffect not get called though the state gets updated? Is it because of the state mutation?

Second Question: Why is there no warning or error thrown regarding a state mutation? State mutations are dangerous - If it happens, I'd expect some sort of warning.

Live demo here:

Edit 7wzlo8y4m1

Tholle

The array you pass as second argument to useEffect only checks if the elements in the array are === to the elements in it in the previous render. const newArr = arr; will lead to newArr === arr since it doesn't create a new array, which is not what you want.

Create a new array with all the elements in arr and it will work as expected.

const App = props => {
 const { arr, setArr } = useContext(GlobalContext)

 const handleChange = () => {
   const newArr = [...arr]
   [10, 20, 30, 40].forEach(v => {
     newArr.push(v)
   })
   setArr(newArr)
 }

  return <>{/* ... */}</>
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Setting state in useEffect hook does not change state value

componentDidUpdate not firing after redux state change

(React) setState() callback not firing after state change

Testing Custom Hook and useEffect Not Firing

Setting State in Useeffect Hook

useEffect not re-rendering after state change

useEffect not getting trigger after state change

useEffect triggers after second state change Reactjs

useEffect() Hook doesn't update when State Change

state value does not change when using useEffect hook

Setting hook state inside React useEffect hook

Why is my React state undefined even after setting the state in UseEffect hook?

How can i prevent useEffect() from firing up the first time but listening for a state change?

emberjs | beforeModel hook is firing after model hook

Why does the useEffect hook execute when there's a change in Redux state, even if that specific state is not included in the hook's dependency array?

How to conditionally change state in useEffect after a delay in React?

usestate can change the state value after axios in useEffect

Skip hook change (useEffect) on initialize

In react useEffect hook my functions are called but only first function can change the state second function can't change the state

Delayed state change in hook

How to fix missing dependency warning when using useEffect Hook to update state when props change

React why does my useEffect hook that retrieves local storage break after wrapping my state in context?

How to set the state inside useEffect hook?

How to reset React hook state with setTimeout in useEffect

Can I set state inside a useEffect hook

Referencing outdated state in React useEffect hook

React update state array in useEffect hook

Unable to set state in useEffect hook React

cannot set state inside useEffect hook