State and Lifecycle of React Components
Tags: react, webdev, programming, javascript
Published: 2021-01-20 23:10:36

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

In this article, we’ll look at the lifecycle of React components and how to change their internal state.

Changing Internal State
=======================

Props are immutable since we want to keep React components pure with respect to props. This means that when we pass in the same props, we always get the same output assuming nothing else changes.

This isn’t very useful in most cases since we want to change things inside a component.

To do this, we can manipulate the internal state of a component.

All class-based React components have internal state accessible via `this.state`, and we can change it by calling `this.setState`.

For example, if we want to create a `Clock` component that shows the current time and updates it every second, we can do that as follows:

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

  componentWillMount() {  
    this.updateDate();  
  } 

  componentWillUnmount() {  
    clearInterval(this.state.timer);  
  } 

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

  render() {  
    return (  
      <div>  
        <p>It is {this.state.date.toLocaleTimeString()}.</p>  
      </div>  
    );  
  }  
}
```

In the code above, we declared a class `Clock` that extends `React.Component`. This means the code is a React component, which can have its own lifecycle methods and the `render` method.

Inside the `Clock` component, we declared the `state` field in the `constructor` which has the initial state `date`, and a `timer` state to hold the timer object that’s returned by `setInterval`.

Also, we called `super(props)` since `Clock` extends `React.Component`, and the `React.Constructor` takes `props` as an argument.

Then we have our `componentDidMount` lifecycle hook to load the initialization code when the `Clock` component is mounted into the DOM.

The `updateDate` method is called in `componentDidMount` to continuously update the `this.state.date` every second.

To update the date inside the `setInterval` callback, we called `this.setState` with an object inside.

The object has the state’s name as the key as we defined it in the first line, and the value is the new value that we want to set the state to.

We also called `setState` to set the `timer` field so that we can call `clearInterval` with it inside the `componentWillUnmount`. The `componentWillUnmount` hook is called when the component is removed from the DOM.

It’s a good place to run any code that’s used to clean things up.

Finally, in the `render` method, we render the date. This method is called whenever `this.state` changes by calling `this.setState`, so if we put `this.state` properties in there, the latest value of it will always be shown.

This means that `this.state.date` will be the latest date after:

```
this.setState({ date: new Date() });
```

is called.

`componentDidMount` and `componentWillUnmount` are lifecycle methods. They’re called only in specific parts of a React component’s lifecycle.

`this.setState` is asynchronous, so we shouldn’t assume that code that’s listed after a `this.setstate` call will run immediately after `this.setState`.

To mount it in the DOM, we call the `ReactDOM.render` method with `Clock` passed in as follows:

```
import React from "react";  
import ReactDOM from "react-dom";

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

  componentWillMount() {  
    this.updateDate();  
  } 

  componentWillUnmount() {  
    clearInterval(this.state.timer);  
  } 

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

  render() {  
    return (  
      <div>  
        <p>It is {this.state.date.toLocaleTimeString()}.</p>  
      </div>  
    );  
  }  
}

const rootElement = document.getElementById("root");  
ReactDOM.render(<Clock />, rootElement);
```

Using State Correctly
=====================

We should never modify the state directly because it won’t trigger a re-rendering of a component.

So we shouldn’t write:

```
this.state.foo = 'bar';
```

Instead, we should always use `this.setState` as follows:

```
this.setState({foo: 'bar'});
```

State Updates May Be Asynchronous
=================================

State updates are asynchronous, so we shouldn’t depend on it run one after the other.

Also, we can’t just combine `props` and `state` values within `setState` .

For example, the following may fail:

```
this.setState({  
  count: this.state.count + this.props.increment,  
});
```

Instead, we write:

```
this.setState((state, props) => ({  
  count: state.count + props.increment  
}));
```

to get the latest values from `props` to update the code.

Regular and arrow functions both work, so we can also write:

```
this.setState(function(state, props) {  
  return {  
    count: state.count + props.increment  
  };  
});
```

State Updates are Merged
========================

When we call `setState`, React merges the object that we pass into `setState` into the current state.

For example, if we have 2 states, `firstName` and `lastName`, then when we called `this.setstate({ lastName });`, `this.state.firstName` stays intact, while `this.state.lastName` is updated with the latest value of `lastName`.

Data Flows Down
===============

States are always inside a component, and it can be passed down to child components and elements as props.

React apps has a unidirectional data flow that goes from parent to child.

Conclusion
==========

We can create a React component that is dynamic by storing states inside a component.

The state object is stored in the `state` field of the React component class.

We can set the state by running `this.setState`.

React components have lifecycles that trigger methods in the React component class. These are called lifecycle hooks.

We can use them to run code at certain stages of a React component’s lifecycle.