Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing array to useEffect dependency list

There's some data coming from long polling every 5 seconds and I would like my component to dispatch an action every time one item of an array (or the array length itself) changes. How do I prevent useEffect from getting into infinity loop when passing an array as dependency to useEffect but still manage to dispatch some action if any value changes?

useEffect(() => {   console.log(outcomes) }, [outcomes]) 

where outcomes is an array of IDs, like [123, 234, 3212]. The items in array might be replaced or deleted, so the total length of the array might - but don't have to - stay the same, so passing outcomes.length as dependency is not the case.

outcomes comes from reselect's custom selector:

const getOutcomes = createSelector(   someData,   data => data.map(({ outcomeId }) => outcomeId) ) 
like image 664
user0101 Avatar asked Dec 24 '19 10:12

user0101


People also ask

How do you pass an array in useEffect?

To pass an array to useEffect dependency list in React, we can pass in the array state into the dependencies list. We have the nums array state we created with the useState hook. Then we call useEffect with a callback that logs the current value of nums .

Does useEffect work with arrays?

This array will re-run useEffect, if the values inside it changes. This will work perfectly fine when the values passed in the dependency array are of type boolean, string or numbers. But it will have some gotchas when you are dealing with complex values such as objects or arrays.

What happens if we don't pass dependency array in useEffect?

Empty dependency array So what happens when the dependency array is empty? It simply means that the hook will only trigger once when the component is first rendered. So for example, for useEffect it means the callback will run once at the beginning of the lifecycle of the component and never again.

How does useEffect dependency array work?

The useEffect hook allows you to perform side effects in a functional component. There is a dependency array to control when the effect should run. It runs when the component is mounted and when it is re-rendered while a dependency of the useEffect has changed.

What is the dependency array in the useeffect hook?

One of the arguments that the useEffect accepts, after the callback function is the dependency array. This array defines the list of variables that if changed will trigger the callback function. Let us take a look at some of the parameters that can be passed in place of the dependency array, and how it affects the hook itself. 1.

What are the additional rules in the dependency array concept?

These additional rules help you catch bugs early like helping you to know what needs to be added to your dependency array - the exhaustive-deps rule. There's more than one hook that uses a dependency array concept, but chances are you'll learn about the dependency array when you learn useEffect which is often one of the first hooks people learn:

Can useref() current be used in a dependency array?

This answer is wrong, useRef ().current can not be used in a dependency array: medium.com/welldone-software/… @flyingsheep It's your argument that is wrong. Did you read the code and try running the demo? ref.current is a middle man variable that is used to store the new value which invokes the effect callback depend on the equality check.

Is it possible to spread an array of objects using useeffect?

Spreading the array is no good. App starts with an empty array as default, so useEffect will throw error about different number of dependencies between rerenders. You can pass JSON.stringify (outcomes) as the dependency list: useEffect ( () => { console.log (outcomes) }, [JSON.stringify (outcomes)]) I'm quite sure this is the answer the OP wants.


2 Answers

You can pass JSON.stringify(outcomes) as the dependency list:

Read more here

useEffect(() => {   console.log(outcomes) }, [JSON.stringify(outcomes)]) 
like image 159
Loi Nguyen Huynh Avatar answered Sep 23 '22 19:09

Loi Nguyen Huynh


Another ES6 option would be to use template literals to make it a string. Similar to JSON.stringify(), except the result won't be wrapped in []

useEffect(() => {   console.log(outcomes) }, [`${outcomes}`]) 

Another option, if the array size doesn't change, would be to spread it in:

useEffect(() => {   console.log(outcomes) }, [ ...outcomes ]) 
like image 45
iPzard Avatar answered Sep 22 '22 19:09

iPzard