Milos
Milos

Reputation: 619

How to properly set state from if statement

I'm trying to update state in useEffect hook, but I came up with a problem with it. Inside the hook I have if statement where I'm setting the data in opacityBar variable, and outside the if i need to update the state with that variable, but it's not working. This is the code I have:

React.useEffect(() => {
   let opacityBar;
   if(filteredData.length > 0) {
      const inc = (name) => filteredData.find((f) => f.name === name) !== undefined;

   opacityBar = coloredBar?.data?.map((bar: any) => ({ ...bar, opacity: inc(bar.name) ? 1 : 0.333 }));
   } else {
      opacityBar = coloredBar?.data?.map((bar: any) => ({ ...bar, opacity: 1 }));
   }

   setColoredBar(opacityBar);
}, [filteredData, coloredBar]);

I've also tried to set state like this setColoredBar({ ...coloredBar, opacityBar }); but this causing an infinite loop. What am I doing wrong here?

Upvotes: 1

Views: 155

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 282160

You shouldn't be adding coloredBar as a dependency to useEffect because you are setting the same state in it. Doing this will lead to an infinite loop.

You can instead use functional setState like below

React.useEffect(() => {

   setColoredBar(coloredBar => {
         let opacityBar;
         if(filteredData.length > 0) {
            const inc = (name) => filteredData.find((f) => f.name === name) !== undefined;
            opacityBar = coloredBar?.data?.map((bar: any) => ({ ...bar, opacity: inc(bar.name) ? 1 : 0.333 }));
         } else {
            opacityBar = coloredBar?.data?.map((bar: any) => ({ ...bar, opacity: 1 }));
         }
         return opacityBar;
   })

}, [filteredData]);

Upvotes: 2

Hagai Harari
Hagai Harari

Reputation: 2877

Because you setColoredBar(opacityBar); inside the effect, and coloredBar is one of the triggers to run the effect, each time you finish the effect you start it again. just add checker to setColoredBar(opacityBar);


opacityBar != coloredBar && setColoredBar(opacityBar);

or if you don't really need coloredBar to be a trigger for re-run the effect, remove it from [dependencies] of the effect

Upvotes: 0

Related Questions