Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
150
rated 0 times [  152] [ 2]  / answers: 1 / hits: 44802  / 5 Years ago, sun, february 10, 2019, 12:00:00

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


More From » reactjs

 Answers
9

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 <>{/* ... */}</>
}

[#52624] Tuesday, February 5, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
luna

Total Points: 698
Total Questions: 114
Total Answers: 93

Location: Israel
Member since Wed, Apr 14, 2021
3 Years ago
luna questions
;