DEV Community

TrèsAbhi
TrèsAbhi

Posted on • Edited on

How to stop infinite loop without breaking React's rule of hooks (useEffect)

I have many different places where I have to use the same logic, so I have generalized my logic system into a class...

...
const contextLayer = new contextLayerCore(...useState([]));
...
Enter fullscreen mode Exit fullscreen mode

This class provides me with a bunch of functions like addContext, removeAll, etc. However, the addContext function is a bit problematic...

...
addContext(context: listing) {
  this.setState([...this.state, context]);
}
...
Enter fullscreen mode Exit fullscreen mode

Simple enough; all it does is append an object using the setState function which should re-render any components using the state. Here's the problem, this causes an infinite loop...

...
this.setState([...this.state, context]);
//                     ^
// also updates when state updates, hence re-runs the setState function
...
Enter fullscreen mode Exit fullscreen mode

This causes and infinite loop. I could using useEffect(..., []) to make it not be dependant, however, this is a function inside a class, thus it breaks React's rules of hooks.

I have to retain the functionality of this class, so I cannot move the function up into the component(s) as a lot of components use this class and would simply create duplicate code.

And example of where it is used...

...
<ContextSuperContainer render={contextLayer.state} />
...
Enter fullscreen mode Exit fullscreen mode

What should I do? Is there an alternative of useEffect? Should I be using a different system for this purpose?

Edit: Solution

Convert it to a custom hook!

export default function useContextLayer (initialState: Array<listing>) {
  const [state, setState] = useState(initialState);

  return {
    removeAll: () => {...},
    addContext: () => {...},
    // doesn't even need an useEffect anymore
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
tresabhi profile image
TrèsAbhi

I was able to solve this by converting the class to a custom hook (which returns and object with my functions).