Mastering Side Effects: The useEffect Hook in React
Connect your components to the outside world for data fetching, subscriptions, and much more.
/* How to connect to the outside world? */
What is a Side Effect?
A side effect is any operation in your component that affects something outside of itself. Common examples include fetching data from an API, setting up a timer with `setInterval`, or manually changing the DOM. The `useEffect` hook provides a way to handle these operations cleanly within functional components.
The Dependency Array: Controlling the Effect
The dependency array is the second argument to `useEffect`, and it controls *when* your effect runs.
- `[]` (empty array): The effect runs only once, after the initial render. Perfect for initial data fetching.
- `[prop, state]` (with values): The effect runs once on mount, and then again any time one of the dependency values changes.
- No array: The effect runs after every single render. Use this with caution as it can cause performance issues.
The Cleanup Function: Preventing Memory Leaks
Some side effects need to be cleaned up to prevent memory leaks, like subscriptions or timers. You can do this by returning a function from your effect. React will execute this cleanup function when the component unmounts, or before the effect runs again.
The Result: Full Lifecycle Management
By mastering `useEffect`, you can manage the entire lifecycle of a component's side effects. This allows you to build complex, stateful components that can interact with the browser and external services reliably, creating a seamless user experience.
Practice Zone
Interactive Test 1: Match the Behavior
Match the `useEffect` dependency array to its execution behavior.
Arrastra en el orden correspondiente.
Arrastra las opciones:
Completa el código:
Interactive Test 2: Complete the Code
Rellena los huecos en cada casilla.
function UserProfile({ userId }) { const [user, setUser] = useState(null); (() => { fetch(`/api/users/${userId}`) .then(res => res.json()) .then(data => setUser(data)); }, []); return <div>{user?.name}</div>; }
Practice Example: Code Editor
Fetch data from the API endpoint `https://jsonplaceholder.typicode.com/todos/1` when the component mounts and display the todo's title.
`useEffect` in Action
`useEffect` is the bridge between React's declarative world and the imperative world of browser APIs, network requests, and third-party libraries. Here are some practical examples.
1. Fetching Data on Load
The most frequent use case for `useEffect`. An empty dependency array (`[]`) ensures the fetch only happens once when the component mounts, preventing unnecessary network requests on re-renders.
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/user/1')
.then(res => res.json())
.then(data => setUser(data));
}, []); // Runs only once!
Result:
2. Responding to Prop Changes
When you pass a value to the dependency array, the effect will re-run whenever that value changes. This is perfect for fetching new data when a user navigates to a different item.
function UserProfile({ userId }) {
useEffect(() => {
// Fetches data for the new userId
fetch(`/api/users/${userId}`);
}, [userId]); // Re-runs when userId changes
}
Fetches user 3...
3. Cleaning Up Subscriptions
If your effect subscribes to something (like a WebSocket or a browser event), you must clean it up to avoid memory leaks. The returned function from `useEffect` is the perfect place for this logic.
useEffect(() => {
const handleResize = () => { /*...*/ };
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
Practical Takeaway: Think of `useEffect` as a way to synchronize your React component with an external system. Use the dependency array to control *when* that synchronization happens.
`useEffect` Glossary
- Side Effect
- Any operation that interacts with the world outside of a component's render cycle, such as API calls, subscriptions, timers, or direct DOM manipulation.
- useEffect Hook
- A React Hook that lets you perform side effects in functional components. It runs after the component has rendered to the screen.
- Dependency Array
- The optional second argument to `useEffect`. It's an array of values that the effect depends on. The effect will only re-run if one of these values has changed between renders.
- Cleanup Function
- A function that can be returned from an effect. React runs the cleanup function before the component unmounts and before re-running the effect due to dependency changes.
- Mount / Unmount
- "Mounting" is the process of React rendering a component to the DOM for the first time. "Unmounting" is when the component is removed from the DOM.