React Tutorial – Learn React in 5 hours – Part 2

react class component
Share

As we already discussed briefly about this topic in the previous section of React Tutorial . Now we are discussing in detail about class component

Class components were the only way to track state and lifecycle on React components before React 16.8. Function components were considered “stateless.”.

React’s Function components are almost as powerful as its Class components, with the difference that you probably won’t need to use a Class component.

Class components are not being removed from React at the moment, even though Function components are preferred.

If you prefer, you can skip this class component and use Function Components instead.

 

Create a Class Component

A React component’s name must begin with an upper case letter.

Class components must include the extends React.Component statement. As a result of this statement, your component inherits React.Component and has access to React.Component’s functions.

The component also requires a render() method, this method returns HTML.

Example:
Create a Class component called Bike

class Bike extends React.Component {
 render() {
   return <h2>Hi, I am a Bike!</h2>;
 }
}
The Bike component in your React application returns a <h2> element. To use this component in your React application, use the following syntax: <Bike />
Example:
Display the Bike component in the "root" element:

ReactDOM.render(<Bike />, document.getElementById('root'));
Output:
Create a class component

Component Constructor

A constructor() function in your component is called when it’s initialized.

In the constructor function, you set the component’s properties.

Component properties should be kept in a state object in React.

Later in this tutorial, we will discuss state in more detail.

By using the super() statement in the constructor function, you honor the inheritance of the parent component, and your component has access to all its functions (React.Component).

Example:
Create a constructor function in the Car component, and add a color property:

class Bike extends React.Component {
  constructor() {
    super();
    this.state = {color: "black"};
  }
  render() {
    return <h2>I am a Bike!</h2>;
  }
}
Use the color property in the render() function:
Example:
class Bike extends React.Component {
  constructor() {
    super();
    this.state = {color: "black"};
  }
  render() {
    return <h2>I am a {this.state.color} Bike!</h2>;
  }
}
Output:

Props

Using props is another way of managing component properties.

Props are like function arguments, and you pass them into the component as attributes.

In the previous chapter, you learned about props.

Example:
You can pass a color into the Bike component's attribute and use it in the render() function:

class Bike extends React.Component {
  render() {
    return <h2>I am a {this.props.color} Bike!</h2>;
  }
}

ReactDOM.render(<Bike color="red"/>, document.getElementById('root'));
Output:
Props

Props in the Constructor

Components with constructor functions should pass their props to the constructor and also to the React.Component using the super() method. 

Example:
class Bike extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <h2>I am a {this.props.model}!</h2>;
  }
}

ReactDOM.render(<Bike model="Splendor"/>, document.getElementById('root'));
Output:
Props in the Constructor

Components in Components

There are several ways of referring to components inside other components:

Example:
Use the Bike component inside the Garage component:

class Bike extends React.Component {
  render() {
    return <h2>I am a Bike!</h2>;
  }
}

class Garage extends React.Component {
  render() {
    return (
      <div>
      <h1>Who lives in my Garage?</h1>
      <Bike />
      </div>
    );
  }
}

ReactDOM.render(<Garage />, document.getElementById('root'));
Output:
Components in Components

Components in Files

In React, re-using code is the goal, so you may want to separate some of your components into their own files. 

To do that, create a new .js file and paste the code inside it.

Note that the file must start by importing React (as before), and it has to end with the statement export default Bike;

Example:
This is the new file, we named it Bike.js:

import React from 'react';
class Bike extends React.Component {
  render() {
    return <h2>Hi, I am a Bike!</h2>;
  }
}

export default Bike;
You must import the file to make use of the Bike component.
Example:
Now, we can use the Bike component in the application as if it were created from the Bike.js file.

import React from 'react';
import ReactDOM from 'react-dom';
import Bike from './Bike.js';

ReactDOM.render(<Bike />, document.getElementById('root'));
Output:
Components in Files

React Class Component State

As we mentioned earlier in the component constructor section, React Class components have a built-in state object that stores property values. 

When the state object changes, the component re-renders.

 

Creating the state Object

In the constructor method, initialize the state object:

Example:
Specify the state object as follows:

class Bike extends React.Component {
  constructor(props) {
    super(props);
    this.state = {brand: "Hero"};
  }

  render() {
    return (
      <div>
        <h1>My Bike</h1>
      </div>
    );
  }
}
The state object can contain as many properties as you like:
Example:
Specify all the properties your component need:

class Car extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      brand: "Hero",
      model: "Splendor",
      color: "black",
      year: 1964
    };
  }

  render() {
    return (
      <div>
        <h1>My Bike</h1>
      </div>
    );
  }
}

Using the state Object

Use this.state.propertyname to reference the state object anywhere in the component:

Example:
Refer to the state object in the render() method:

class Bike extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      brand: "Hero",
      model: "Splendor",
      color: "black",
      year: 1999
    };
  }

  render() {
    return (
      <div>
        <h1>My {this.state.brand}</h1>
        <p>
          It is a {this.state.color}
          {this.state.model}
          from {this.state.year}.
        </p>
      </div>
    );
  }
}
Output:
Using the state Object

Changing the state Object

To set a value in the state object, use this.setState().

If the value of the state object changes, the component will re-render, which means that the output will change accordingly.

Example:
Add a button that has an onClick event to change the color:

class Bike extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      brand: "Hero",
      model: "Splendor",
      color: "black",
      year: 1999
    };
  }

  changeColor = () => {
    this.setState({color: "red"});
  }
  render() {
    return (
      <div>
        <h1>My {this.state.brand}</h1>
        <p>
          It is a {this.state.color}
          {this.state.model}
          from {this.state.year}.
        </p>
        <button type="button"
         onClick={this.changeColor}
        >Change color</button>
      </div>
    );
  }
}
Output: 
Changing the state Object

Whenever the state object is changed, use the setState() method, which ensures that the component knows it has been updated and calls the render() method (and all the other lifecycle methods).

Lifecycle of Components

In React, each component has a lifecycle which you can monitor and handle during its three main phases. 

The three phases are: Mounting, Updating, and Unmounting.

 

Mounting

 Mounting is the process of putting elements into the DOM.

In react, four built-in methods are called, in this order, when mounting a component: 

  1. constructor()
  2. getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

The render() method is required and is always called, the others are optional and are called if they are defined.

1. constructor

When the component is first activated, the constructor() method is called, and it is the natural place to set the initial state and other values.

The constructor() method is called with props as arguments, and you should always call the super(props) method before anything else. This will initiate the parent’s constructor method, so the component will inherit methods from the parent (React.Component).

Example:
Each time you create a component, React calls the constructor method:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "blue"};
  }

  render() {
    return (
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
constructor

2. getDerivedStateFromProps

Before rendering any element(s) in the DOM, the getDerivedStateFromProps() method is called. so it is an ideal place to set the state object.

 It takes state as an argument, and returns an object containing the changes made to the state.

The example below starts with the favorite color being “blue“, but the getDerivedStateFromProps() method changes the favorite color according to the favcol attribute:

Example:
Before the render method, the getDerivedStateFromProps method is called: 

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "blue"};
  }

  static getDerivedStateFromProps(props, state) {
    return {favoritecolor: props.favcol };
  }

  render() {
    return (
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
    );
  }
}

ReactDOM.render(<Header favcol="black"/>, document.getElementById('root'));
Output:
getDerivedStateFromProps

3. render

The render() method is the method that actually outputs the HTML to the DOM.

Example:
A simple component with a simple render() method:

class Header extends React.Component {
  render() {
    return (
      <h1>This is the content of the Header component</h1>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
render

4. componentDidMount

A componentDidMount() method is called after it is rendered.

The statements here require that the component is already in the DOM.

Example:
At first my favorite color is blue, but give me a second, and it is black instead:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "blue"};
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({favoritecolor: "black"})
    }, 1000)
  }

  render() {
    return (
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
componentDidMount

 

Updating

Updates are the next phase in the lifecycle of a component.

A component is updated whenever it‘s state or props change.

React has five built-in methods that gets called, in this order, when a component is updated:

  1. getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

There is only one required method, render(), that will always be called, the other methods are optional and will be called if they are defined.

1. getDerivedStateFromProps

When an object is updated, the getDerivedStateFromProps method is called. This is the first method that is called when an object is updated.

Based on the initial props, this is still the logical place to set the state object.

The example below shows a button that changes the favourite color to blue, but since the getDerivedStateFromProps() method is called, which updates the state with the color from the favcol attribute, the favourite color remains yellow:

Example:
If the component gets updated, the getDerivedStateFromProps() method is called:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "red"};
  }

  static getDerivedStateFromProps(props, state) {
    return {favoritecolor: props.favcol };
  }

  changeColor = () => {
    this.setState({favoritecolor: "blue"});
  }

  render() {
    return (
      <div>
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
      <button type="button" onClick={this.changeColor}>Change color</button>
      </div>
    );
  }
}

ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
Output:
getDerivedStateFromProps

2. shouldComponentUpdate

The shouldComponentUpdate() method returns a Boolean value indicating whether React should continue rendering the component.

The default value is true.

Below is an example of what happens when the shouldComponentUpdate() method returns false:

Example:
Stop the component from rendering at any update:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "red"};
  }

  shouldComponentUpdate() {
    return false;
  }

  changeColor = () => {
    this.setState({favoritecolor: "blue"});
  }

  render() {
    return (
      <div>
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
      <button type="button" onClick={this.changeColor}>Change color</button>
      </div>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
shouldComponentUpdate
Example:
Here is the same example as above, but now the shouldComponentUpdate() method returns true instead:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "red"};
  }

  shouldComponentUpdate() {
    return true;
  }

  changeColor = () => {
    this.setState({favoritecolor: "blue"});
  }

  render() {
    return (
      <div>
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
      <button type="button" onClick={this.changeColor}>Change color</button>
      </div>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
shouldComponentUpdate

3. render

Whenever a component is updated, the render() method is called so that the HTML is rendered to the DOM. Below is an example of a button that changes the favorite color to blue:

Example:
Change the component's state by clicking the button:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "red"};
  }

  changeColor = () => {
    this.setState({favoritecolor: "blue"});
  }

  render() {
    return (
      <div>
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
      <button type="button" onClick={this.changeColor}>Change color</button>
      </div>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
render

4. getSnapshotBeforeUpdate

GetSnapshotBeforeUpdate() provides access to the props and state before the update, so even after the update, you can see what the values were.

You should also include the componentDidUpdate() method if the getSnapshotBeforeUpdate() method is present, otherwise you will get an error.

Here’s an example that may seem complex, but all it does is render the component’s favorite color “red” when mounting.

Within one second of mounting the component, the favorite color changes to yellow.

Since this component has a getSnapshotBeforeUpdate() method, this method is called, and it writes a message to the empty DIV1 element.

The componentDidUpdate() method executes and displays the following message in the empty DIV2 element:

Example:
If you want to see how the state object looked before the update, you can use the getSnapshotBeforeUpdate() method:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "red"};
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({favoritecolor: "yellow"})
    }, 1000)
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    document.getElementById("div1").innerHTML =
    "Before the update, the favorite was " + prevState.favoritecolor;
  }

  componentDidUpdate() {
    document.getElementById("div2").innerHTML =
    "The updated favorite is " + this.state.favoritecolor;
  }

  render() {
    return (
      <div>
        <h1>My Favorite Color is {this.state.favoritecolor}</h1>
        <div id="div1"></div>
        <div id="div2"></div>
      </div>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
getSnapshotBeforeUpdate

5. componentDidUpdate

The componentDidUpdate method is invoked immediately after the component is updated in the DOM.

The following example might seem complex, but it just does what it says:

The component is rendered with the color “red” when mounting.

As soon as the item is mounted, the timer changes its state, and the color changes to yellow.

The action triggers the update phase, and this component has a componentDidUpdate method, which executes and displays the following message in the empty DIV element:

Example:
After the update is rendered in DOM, the componentDidUpdate method is called:

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {favoritecolor: "red"};
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({favoritecolor: "yellow"})
    }, 1000)
  }

  componentDidUpdate() {
    document.getElementById("mydiv").innerHTML =
    "The updated favorite is " + this.state.favoritecolor;
  }

  render() {
    return (
      <div>
      <h1>My Favorite Color is {this.state.favoritecolor}</h1>
      <div id="mydiv"></div>
      </div>
    );
  }
}

ReactDOM.render(<Header />, document.getElementById('root'));
Output:
componentDidUpdate

 

Unmounting

React calls this phase of the lifecycle “unmounting,” or removing the component from the DOM.

When a component is unmounted, React calls only one built-in method:

  • componentWillUnmount()

componentWillUnmount

DOM components are about to be unmounted when the componentWillUnmount method is called.

Example:
Click the button to delete the header:

class Container extends React.Component {
  constructor(props) {
    super(props);
    this.state = {show: true};
  }

  delHeader = () => {
    this.setState({show: false});
  }

  render() {
    let myheader;
    if (this.state.show) {
      myheader = <Child />;
    };

    return (
      <div>
      {myheader}
      <button type="button" onClick={this.delHeader}>Delete Header</button>
      </div>
    );
  }
}

class Child extends React.Component {
  componentWillUnmount() {
    alert("The component named Header is about to be unmounted.");
  }

  render() {
    return (
      <h1>Hello World!</h1>
    );
  }
}

ReactDOM.render(<Container />, document.getElementById('root'));
Output:
componentWillUnmount

In next section, we will discuss about functional component with hooks information.

Share

Leave a Comment

Your email address will not be published.

Share