Skip to main content

How to think about useEffect?

useDefect or useFootGun πŸ¦ΆπŸΌπŸ”«β€‹

Yes, I'm not kidding, useEffect can produce hard-to-understand, un-maintainable, unpredictable code. Chained useEffects can also produce cascading chain reactions of unpredictability if not used properly. In most cases, you do not need useEffect, it can be handled with event driven approach.

But that doesn't mean there's no use of useEffect. It's primary use is to handle subscriptions. When the component mounts you want to subscribe to some-stuff, and then when the component un-mounts, you cleanup the subscriptions.

tip

Think of useEffect as useSynchronize

Imagine you're watching TV, if you change channels, the content of that TV channel doesn't stop coming, You just don't care about that content anymore, that's all. useEffect helps you subscribe to the desired channel, consume content and when you're done, you can unsubscribe.

React 18 made it clear​

In React 18, the following code will run twice, not once!

BAD πŸ’©πŸ§¨πŸ’£
function App() {
// ...

useEffect(() => {
authenticate();
}, []);

// ...
}
  • It's react's way of telling you, you're not using useEffect as intended!
  • Your components must be robust to component updates and mounts.
Hack | Workaround
let initialized = false;

function App() {
//...

useEffect(() => {
if (!initialized) {
initialized = true;
authenticate();
}
}, []);

// ...
}
Or just remove the useEffect all-together βœ…
// If you're using Next.JS check you're running in browser
if (typeof window !== 'undefined') {
// βœ… Only runs once per app load
authenticate();
}

function App() {
//...
}