Register to get access to free programming courses with interactive exercises

useEffect Hook JS: React Hooks

To carry out side effects, for example, working directly with the DOM in React, we use the built-in useEffect(). It replaces three life cycle callbacks:

  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()

If you forgot or didn't know how they work, then you can read more about it in the official documentation.

Let's start with a simple example:

import React, { useState, useEffect } from 'react';

const Example = () => {
  const [count, setCount] = useState(0);

  // Works like componentDidMount and componentDidUpdate combined
  // Starts after rendering the component
  // Called after each click on the button
  useEffect(() => {
    // The state is accessible internally, as the scope is normal
    alert(`Clicks ${count}`);
  });

  // With classes, we'd do this
  // Note the duplication
  // componentDidMount() {
  //   alert(`Clicks: ${count}`);
  // }
  // componentDidUpdate() {
  //   alert(`Clicks: ${count}`);
  // }

  return (
    <div>
      <p>You clicked {count} time(s)</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
};

Below is an example in which the background changes with each click.

The callback passed to useEffect() is processed after the component's first rendering, and after each update. In othe words, the componentDidUpdate() and componentDidMount() methods were combined. This change was made for convenience. Worldwide practice using React has shown that, essentially, effects occur after each render, regardless of whether this is the first rendering or subsequent ones. As a bonus, the amount of duplication and code has been reduced. What are typical side effects found in the frontend? For example:

  • Data extraction
  • Working with the BOM(Browser Object Model) API, e.g., Local Storage
  • Direct DOM modification, this also includes libraries that are incompatible with React

The action of the useEffect() hook can sometimes be skipped. This can be useful either for optimization purposes, or if the effect is only of use under certain conditions. To do this, an array of values that must be tracked between renderings is passed to the hook as the second argument. If at least one value from this array has changed, the callback is called, if all values remain the same, it is skipped.

useEffect(() => {
  alert(`Clicks ${count}`);
}, [count]);

// Equivalent
componentDidUpdate(prevProps, prevState) {
  if (prevState.count !== this.state.count) {
    alert(`Clicks ${count}`);
  }
}

I.e., the callback will be called only when the count changes. In the same way, you can pass any set of variables that we'd like to associate with the effect change. If at least one variable in the passed array has changed, the effect will work, otherwise React will skip it.

What should I do if I need to run useEffect() only when the first render occurs (immediately after mounting)? To do this, you just need to pass an empty array:

// Replaces componentDidMount

useEffect(() => {
  alert(`Clicks ${count}`);
}, []);

This solution isn't the most obvious, but technically, it's not a special case. You just need to get used to it.

Resetting the effect

In some cases, the effect needs to be reset. For example, when the effect after changing the props ceases to be relevant, it needs to be "cleaned up". To do this, you just need to return the function from useEffect(), and the cleanup is carried out inside.

// Let's assume that this effect depends on the userId prop
useEffect(() => {
  const id = setTimeout(/* some code with userId */);

  return () => clearTimeout(id);
}, [userId]);

Changing the userId will reset the current timer and install a new one. This kind of code in classes would require the use of as many as 4 life cycle callbacks.

To simulate componentWillUnmount() just connect the cleanup to an empty array with a second parameter:

useEffect(() => {
  return () => {
    // This logic will be executed only when the component is unmounted
  };
}, []);

Recommended materials

  1. Using the Effect Hook
  2. Why Effects Run on Each Update

Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Profession
beginner
Development of front-end components for web applications
start anytime 10 months

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.