Register to get access to free programming courses with interactive exercises

Component lifecycle JS: React

When you use React correctly, most components consist of the render method and event handlers:

class ArticleItem extends React.Component {
  handleClick = (e) => {
    e.preventDefault();
    const { onClick } = this.props;
    onClick();
  }
  render() {
    const { name, description, link } = this.props;
    return (
      <div>
        <a href="{link}" onClick={this.handleClick}>{name}</a><br />
        <div>{description}</div>
      </div>
    );
  }
}

But not all problems are solved so easily. Imagine a <Clock /> component that simulates a digital clock in hh:mm:ss format:

class Clock extends React.Component {
  render() {
    const currentTime = new Date();
    return (
      <div>{currentTime.toLocaleTimeString()}</div>
    );
  }
}

This component displays the current time. Now we have to figure out how to update it. A clock, unlike conventional components, does not expect action from the user. They update themselves every second. We end up with a chain: an event happens => the current time changes => React calls render and changes the DOM.

So, the current time initializes the state:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { date: new Date() };
  }
  render() {
    const { date } = this.state;
    return (
      <div>{date.toLocaleTimeString()}</div>
    );
  }
}

The component still shows the current time when it is rendered. But it's now ready to change.

Time refers to periodic events for which we use timers. It is fine to use setInterval for <Clock />. We should set the timer immediately after rendering the clock. And we should clear it when we remove the component from the item tree:

setInterval(() => this.setState({ date: new Date() }), 1000);

When do we start the timer? We call render whenever the state changes, so it's not the right option. Because then <Clock /> will start a new timer every second. The constructor seems like a more appropriate place, but there is something else here.

Calling the constructor and rendering the clock in the DOM tree are generally independent events. Look at this code:

// We call the constructor
const clock = <Clock />;

// Something is taking a long time

// Rendering
const root = createRoot(document.getElementById('root'));
root.render(clock);

This clock isn't in the DOM tree yet, but it's already running. Is it worth worrying about? Yes, this behavior is unexpected. It interferes with testing and wastes CPU time. In addition, the constructor doesn't remove the timer in any way.

Each React component goes through several stages in its life: we create it, add it to the DOM, then it receives props, and we finally remove it from the tree. This process is called the Component Lifecycle.

React provides a set of methods to integrate into this process. For example, we can start the clock immediately after rendering it. The componentDidMount method can help with this. It's called immediately after rendering a component. It happens only once:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { date: new Date() };
  }

  componentDidMount() {
    // We save the timer identifier
    this.timerId = setInterval(() => this.setState({ date: new Date() }), 1000);
  }

  render() {
    const { date } = this.state;
    return (
      <div>{date.toLocaleTimeString()}</div>
    );
  }
}

Note how we store the timer inside the object. It's not involved in the view, so there's no need to use the state.

Now you need to clear the timer. We execute the method componentWillUnmount just before we remove the component from the DOM:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { date: new Date() };
  }

  componentDidMount() {
    this.timerId = setInterval(() => this.setState({ date: new Date() }), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timerId);
  }

  render() {
    const { date } = this.state;
    return (
      <div>{date.toLocaleTimeString()}</div>
    );
  }
}

The clock now looks finished.

So, you've learned two methods to build into a component's lifecycle, but there are many more. We can divide them into three independent groups.

Mounting

We call these methods when the object is created and placed into the DOM:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

Updating

Updating can occur when properties or states change. We call these methods during rerendering:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

Unmount

There's one method in this group. We call it when we remove a component from the DOM:

  • componentWillUnmount()

There are many methods, but only a few are used regularly in real projects. For example, the method componentDidMount is used pretty often. It helps to set timers, make AJAX requests, and change the DOM to bypass React. The latter is necessary when integrating with third-party libraries.


Recommended materials

  1. State and Lifecycle

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
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

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.