Learn why side effects like API calls belong in the useEffect hook. Distinguish between rendering and side effects to build predictable React applications.
Previously in this course, we mastered Introduction to React State: Making Your UI Interactive to keep our components dynamic. While state manages the data that drives your UI, your application eventually needs to "reach out" to the world beyond your component’s internal logic. This lesson introduces side effects, the primary mechanism for handling these external interactions.
In Introduction to Component-Based Architecture in React, we discussed how React components should ideally be "pure." A pure function (or component) calculates its output based solely on its inputs (props and state) without modifying anything outside its scope.
A side effect is any operation that reaches outside the component to interact with the world. Common examples include:
If you perform these actions directly inside the body of your component function, you break the contract of purity. Because React calls your component function every time it needs to re-render, any code placed directly in the function body will execute every single time the component renders. This leads to performance bottlenecks, infinite loops, and erratic UI behavior.
To understand the difference, think of your component as a calculation engine:
By separating these, you allow React to handle the UI update efficiently while you handle the "messy" external work in a controlled environment.
useEffectReact provides the useEffect hook to encapsulate these side effects. By wrapping your logic in useEffect, you tell React: "Do not run this code during the render phase. Wait until the component has finished painting the UI to the screen."
Here is the basic syntax:
JAVASCRIPTimport { useEffect } from CE9178">'react'; function MovieBrowser() { useEffect(() => { // Your side effect logic goes here console.log("The component has rendered or updated."); }); return <div>Movie Browser</div>; }
Let’s advance our movie-browser project. Suppose we want the browser tab title to reflect the movie search query as the user types.
We shouldn't try to manipulate document.title directly inside the component body, as it would re-run on every single keystroke, causing unnecessary overhead. Instead, we use useEffect.
JAVASCRIPTimport { useState, useEffect } from CE9178">'react'; function MovieSearch({ query }) { // We use the state we learned in previous lessons const [resultsCount, setResultsCount] = useState(0); useEffect(() => { // This runs AFTER the render document.title = CE9178">`Searching for: ${query}`; }); return ( <div> <h1>Movie Browser</h1> <p>Results for "{query}": {resultsCount}</p> </div> ); }
By moving the title update into useEffect, we ensure that the React component remains focused on its primary job—returning JSX—while the browser title is updated as a secondary, synchronized operation.
In your movie-browser project, locate your main search component.
useEffect from 'react'.useEffect block that logs the current search query to the console.fetch() calls or localStorage writes directly in the function component body. It will trigger infinite loops because an API call usually updates state, which triggers a re-render, which triggers the API call again.useEffect without a dependency array will run after every render. This is rarely what you want.Side effects are necessary for real-world applications, but they must be isolated from the render logic to maintain performance and predictability. The useEffect hook is your tool for scheduling these operations to run after React has committed updates to the DOM. By keeping your render function pure and pushing side effects into useEffect, you ensure your app remains performant and easy to debug.
Up next: useEffect Dependencies — learn how to control exactly when your effects run so you don't trigger unnecessary API calls or DOM updates.
Learn to create custom hooks in React to abstract complex data-fetching logic. Improve your code reusability and simplify your components by building a useFetch.
Read moreMaster the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.
Introduction to Side Effects
Polishing the UI
Finalizing the Movie Browser
Review of Component Lifecycle
Review of State Management
Building a Modal Component
Introduction to PropTypes
Performance Optimization Basics
Handling Browser History
Working with LocalStorage
Building a Favorites List
Handling Media in React
Introduction to Testing
Debugging React Apps
Deployment Basics
Using External Libraries
Advanced