Demystify React’s most misunderstood hook by learning to synchronize side effects like data fetching and timers. We break down dependency array patterns and cleanup functions to help you avoid infinite loops.

The mental model for useEffect should be synchronization, not lifecycle. It is not about when a component was born or died, but about ensuring the external system stays in sync with the current state of the UI.
Explain useEffect as syncing React with outside world like fetching data or timers. Cover dependency array meaning: empty, none, specific values. Mention cleanup briefly.


This behavior is often a result of React 18’s Strict Mode in development, which intentionally runs effects twice to stress-test your cleanup logic. If your effect doesn't have a proper cleanup function, these multiple executions can lead to bugs. It can also happen if you omit the dependency array entirely, causing the effect to fire after every single render, or if you have an "infinite loop" where the effect updates a state variable that it also lists as a dependency.
A stale closure occurs when you use an empty dependency array but your effect code relies on props or state variables. Because the empty array tells React to only run the effect once on mount, the effect "captures" the initial values of those variables and never updates them. Even if the component re-renders with new data, the effect remains frozen with the values from the very first render, like a photograph of a moving object.
To avoid an infinite loop, you should use the functional update pattern for state setters, such as setCount(prev => prev + 1). This allows you to update the state based on its previous value without actually reading the state variable itself within the effect's scope. By doing this, you can remove the state variable from the dependency array, breaking the feedback loop where the effect triggers a state change that then re-triggers the effect.
Class-based lifecycles like componentDidMount focus on "time" (when a component is born or dies), whereas useEffect is designed for "synchronization." If you only think about the mount phase, you might miss necessary updates when props change. For example, in a chat component, you don't just want to connect when the component appears; you want to stay synchronized with the specific room ID. If the ID changes, useEffect automatically cleans up the old connection and starts a new one to ensure the external system matches the current UI state.
The recommended way to clean up a fetch request is by using an AbortController. You create the controller inside the effect and pass its signal to the fetch call. In the cleanup function (the return statement of the hook), you call controller.abort(). This ensures that if the component unmounts or the dependencies change before the request finishes, the browser ignores the old result, preventing "zombie" data from overwriting the most recent request.
Creado por exalumnos de la Universidad de Columbia en San Francisco
"Instead of endless scrolling, I just hit play on BeFreed. It saves me so much time."
"I never knew where to start with nonfiction—BeFreed’s book lists turned into podcasts gave me a clear path."
"Perfect balance between learning and entertainment. Finished ‘Thinking, Fast and Slow’ on my commute this week."
"Crazy how much I learned while walking the dog. BeFreed = small habits → big gains."
"Reading used to feel like a chore. Now it’s just part of my lifestyle."
"Feels effortless compared to reading. I’ve finished 6 books this month already."
"BeFreed turned my guilty doomscrolling into something that feels productive and inspiring."
"BeFreed turned my commute into learning time. 20-min podcasts are perfect for finishing books I never had time for."
"BeFreed replaced my podcast queue. Imagine Spotify for books — that’s it. 🙌"
"It is great for me to learn something from the book without reading it."
"The themed book list podcasts help me connect ideas across authors—like a guided audio journey."
"Makes me feel smarter every time before going to work"
Creado por exalumnos de la Universidad de Columbia en San Francisco
