DEV Community

Pravin Jadhav
Pravin Jadhav

Posted on

Let's break down `useEffect` in React.

Imagine we're explaining it to someone brand new to coding!

Think of building a house with LEGOs. React components are like LEGO instructions for building parts of your website or app. useEffect is like a special instruction in those LEGO instructions, but it's for things different from actually building the LEGO house.

1. The Main Job: Building the LEGO House (Rendering)

  • React's main job is to take your instructions (your code) and build the LEGO house (what you see on the screen – the user interface or UI). This is called rendering.
  • React is really good at doing this efficiently. It only updates the house when it absolutely needs to change, to keep things fast and smooth.

2. "Side Effects" - Extra Jobs, Not LEGO Building

Now, imagine that besides just building the LEGO house, you need to do some extra jobs. These are things that aren't directly about putting LEGO bricks together, but are still important for the house or the people living in it. These "extra jobs" are "side effects":

  • Turning on the lights in the house: This is something after the house is built, to make it usable.
  • Opening a window because it's hot inside: This is reacting to the environment around the house.
  • Setting an alarm clock inside the house: This is setting up something to happen in the future.
  • Writing a note on the door: This is interacting with the outside world.

In web/app development, "side effects" are similar "extra jobs" that your React component needs to do, besides just showing things on the screen.

Examples of Side Effects in Code:

  • Fetching Data: Getting information from a server (like asking for the weather forecast or a list of products). This is "outside" your React component itself.
  • Setting Timers: Using setTimeout or setInterval to make something happen after a delay or repeatedly.
  • Logging: Using console.log to write messages for debugging.
  • Changing the Document Title: Changing what appears in the browser tab (using document.title = ...).
  • Manually Changing something outside of React's control (less common, but possible in some situations).

3. The Problem: Doing Side Effects at the Right Time

If you try to do these "side effect" jobs directly while React is building the LEGO house (rendering), you can run into problems:

  • Imagine trying to turn on the lights while you're still putting bricks on the roof. It's messy and could go wrong!
  • React gets confused. It's designed to manage the UI. If you mix in side effects directly with the building process, it can disrupt React's efficient updates and cause unexpected behavior or errors.
  • Too many times! You might accidentally run the side effect way too many times when React re-renders, slowing everything down or making things glitchy.

4. useEffect - The "Schedule these Extra Jobs for Later" Instruction

useEffect is React's solution for doing side effects in a clean and organized way. It's like telling React:

"Hey React, I have these 'extra jobs' (side effects) that need to be done. Please schedule them to run after you are completely finished with building and updating the LEGO house (rendering) for this moment."

5. The Basic useEffect Structure

useEffect(() => {
  // ➡️  Put your "side effect" code here!  (Like turning on lights, fetching data)
  console.log("Doing a side effect!");

  // Optional: Cleanup Function (like turning off lights later)
  return () => {
    console.log("Cleaning up a side effect!");
  };

}, []); // ➡️ The "Dependency Array" - We'll explain this next!
Enter fullscreen mode Exit fullscreen mode
  • useEffect(...): You're using the useEffect "instruction" from React.
  • () => { ... }: This is a function. Inside this function, you write the code for your side effect. Think of it as the "instruction manual" for your extra job (like "how to turn on the lights").
  • [] (The Dependency Array - Empty for now): This is a very important part, the [] (empty square brackets). For now, just know that [] means "run this side effect only once, right after the LEGO house is first built (after the initial render)."

6. The Dependency Array - The Controller of When Side Effects Run

The dependency array (that [] at the end of useEffect) is like the remote control for your side effects! It tells useEffect when to run and re-run your side effect code.

Let's look at different "remote control settings":

  • [] (Empty Dependency Array): "Run Once on First Build"

    • useEffect(() => { /* side effect */ }, []);
    • Meaning: "React, run this side effect only one time, right after you've built the LEGO house for the very first time (after the initial render). Don't run it again unless the whole house is taken down and rebuilt from scratch later (component unmounts)."
    • Use it for: Things you only need to set up once when the component appears, like:
      • Fetching initial data when the page loads.
      • Setting up a connection to something (like a chat server) when the component is shown.
      • Setting up a timer that runs for the lifetime of the component.
  • [someValue] (Dependency Array with Variables): "Run When These Things Change"

    • useEffect(() => { /* side effect using someValue */ }, [someValue]);
    • Meaning: "React, run this side effect:
      • Right after the LEGO house is first built.
      • And then run it again EVERY time someValue changes."
    • someValue could be: A piece of your data (state variable), a prop that gets passed to your component, etc.
    • Use it for: Side effects that need to react to changes in your data, like:
      • Fetching data based on a search term that the user types in. If the search term changes, you want to fetch new data.
      • Updating something on the screen whenever a specific data variable changes.
      • Setting up a timer that depends on a certain setting (e.g., a countdown timer that starts when a specific time value is reached).
  • (Don't Usually Do This!) No Dependency Array (Leave it out Completely): "Run After Every Build - Be Careful!"

    • useEffect(() => { /* side effect */ }); (Notice: no [] or [values]!)
    • Meaning: "React, run this side effect after every single time you update and show the LEGO house on the screen. No matter what changes, just run it after every render."
    • USE WITH CAUTION! This can often lead to your side effect running too much and causing performance problems or infinite loops if you're not careful. You usually want to control when it runs using a dependency array ([] or [values]).

7. Cleanup Function - Tidy Up Your Messes!

Sometimes, your side effects might "make a mess" or "leave things running" even when you don't need them anymore. For example:

  • Timers: If you start a timer in a side effect, you should stop it when the component is no longer needed, otherwise, it might keep running in the background.
  • Event Listeners: If you start listening for events (like mouse clicks), you should stop listening when you're done, to avoid memory leaks.
  • Network Requests: If you start fetching data, and then the component unmounts before the data comes back, you might want to cancel the request to avoid errors or wasted work.

The cleanup function in useEffect is your "tidy-up crew." It's a function you can return from your main side effect function:

useEffect(() => {
  // ➡️  Your main side effect code (start a timer, etc.)

  return () => {
    // ➡️  Your cleanup code! (stop the timer, cancel the request, etc.)
    console.log("Cleaning up!");
  };
}, [dependencies]);
Enter fullscreen mode Exit fullscreen mode

React will run this cleanup function:

  • Right before your main side effect function is about to run again (if the dependencies change).
  • When the component is being removed from the screen (unmounting).

In Simple Words (Summary):

  • useEffect is for doing "extra jobs" (side effects) in React components, after React updates the screen.
  • The dependency array is your "remote control" for deciding when these extra jobs run (or re-run). [] = run once initially. [values] = run when values change.
  • The cleanup function is for tidying up any messes or stopping things you started in your side effect when they are no longer needed.

Think of useEffect as a way to tell React: "Schedule these extra tasks for me, but only do them at these specific times (controlled by the dependency array), and make sure to clean up afterward if needed."

Experiment with the code examples, play around with the dependency array, and you'll start to see how useEffect helps you manage side effects cleanly in React!

Top comments (0)