Understanding Class Component and Functional Component in ReactJS

May 3, 2020
by Moiz Shaikh
  • react component

If you are just starting out with ReactJS, understanding Class, and Functional component is really important. Knowing when to use either of them will allow you to write a clean code and keep your app much more maintainable. Although in a react application, you can have as many Class or Functional components as you like, but a good approach is to always use as less Class components as possible and maximize the use of Functional component.

Class Components in React

Counter.js
import React, {Component} from 'react';

class Counter extends Component{

  state = {
  }

  render(){
    return "Current Counter value is 0";
  }
}

export default Counter;

A class component is created by extending the React.Component which will allow you to inherit its functions. The above is a simplest class component consisting of a render method and an object called as state. A render method in a class component is mandatory which must return something. The render method first runs before a component is mounted. There on the react app will execute the render method whenever the state or props are changed.
 

React State

 A state in a react component is used to maintain data. Its job is to store and keep track of changing data throughout a components lifetime. Prior to React 16.8, this functionality was exclusive to Class based components. In React 16.8, React Hooks were introduced which allowed users to store state in Functional components as well.

Let us extend the above example and add some state in the Counter Component.

Counter.js
class Counter extends Component{
 
  state = {
    counter: 0
  }
   
  increment = () => {
    this.setState((prevS) => ({
        counter: prevS.counter + 1
    }))
  }

  decrement = () => {
    this.setState((prevS) => ({
        counter: prevS.counter1
    }))
  }

  render() {
    return <div className = “container”>
            <p>Current counter values is: {this.state.counter}</p>
            <div className = “buttons”>
               <button onClick = {this.increment}>Increment</button>
               <button onClick = {this.decrement}>Decrement</button>
            </div>
           </div>
  }
}
export default Counter;

Here, we’ve added a property inside of our state called as counter. This will keep track of the current count. To keep it simple, we will add two buttons, Increment and Decrement. For every increment we’ll add 1 to the counter and subsequently subtract 1 for every decrement. Inside the increment and decrement methods, we use React’s setState() method to manipulate the state object. Whenever you change a state in a class component, it must strictly happen through the setState() method.
 

React lifecycle Hooks

Another important feature that’s available to class components is React lifecycle hook. If you are familiar with Angular, you might have used methods like ngOnChanges(), ngOnInit() etc. React lifecycle methods are more or less the same thing.

These methods are executed at different stages of a components lifecycle. For example, the componentDidMount() method runs whenever a component is mounted in the DOM. This method is ideal for making some API request to fetch data. Other lifecycle methods you might find yourself using frequently are componentWillUnmount(), componentDidUpdate() and shouldComponentUpdate(). I’ll be covering these Lifecycle Hooks in detail in a separate article. Meanwhile if you are still curious to know more about them, the react documentation has it covered very well.

Do not confuse React Hooks with Lifecycle Hooks. As mentioned earlier React Hooks is a feature introduced in React 16.8 which added a lot more functionality to Functional Components.

 

Functional Components in React

Functional components are like any other javascript functions. It accepts props as parameters from its calling component and returns some JSX. Keeping React Hooks aside, as I mentioned earlier a functional component does not have a render method neither does it maintains a state.

In our above example code, let us add a functional component and move the button element inside it. We will then call this component from the class component and pass a reference to the increment and decrement methods.
 

DisplayButtons.js
import React from 'react';

const DisplayButtons = (props) => {
    return <button onClick = {props.clicked}>{props.children}</button>
  }

export default DisplayButtons;

Here the functional component returns an html element and the onClick event is referenced through props.clicked to the increment or decrement method. When a component is called, anything passed between the opening and closing tag can be referenced as props.children inside the called component itself. Let us modify our class component right away to make it more clear.
 

counter.js
import React, { Component } from 'react';
import DisplayButtons from './DisplayButtons';
import './counter.css';

class Counter extends Component{

  state = {
    counter: 0
  }
   
  increment = () => {
    this.setState((prevS) => ({
        counter: prevS.counter + 1
    }))
  }

  decrement = () => {
    this.setState((prevS) => ({
        counter: prevS.counter - 1
    }))
  }

  render() {
    return <div className = "container">
            <p>Current counter values is: {this.state.counter}</p>
            <div className = "buttons">
              <DisplayButtons clicked = {this.increment}>Increment</DisplayButtons>
              <DisplayButtons clicked = {this.decrement}>Decrement</DisplayButtons>
            </div>
          </div>
  }
}

export default Counter;
Here, In the class component, we are essentially passing Increment and Decrement as children when we invoke the <DisplayButton/> component, thus allowing us to reuse it. Inside the DisplayButton component, we reference it as props.children. We’ve also passed ‘clicked’ as a prop to the functional component which references increment and decrement method inside the class component.
If you run the above code you should see something like this.
Output of the above code

Output result

 

Conclusion: When to use Class or Functional component?

If you’ve followed along the example code above, you would have a fair idea of when to use a class or functional component. So to summarise, think of a class component as a container which allows you to store data or status of UI elements like a toggle button and so on. You then break your code into smaller pieces by adding functional components.

In our above example code, we worked our way with one Class and functional component, but in real production application, you might have quite a few class components and a lot of functional components which is absolutely fine. The idea of using them though, remains the same. Keeping your code that way will allow you to reuse your components and keep your React app properly structured.
 

The css file for the above app

counter.css
.container{
  width: 40%;
  margin: 5px auto;  
  background-color: aqua;
  box-sizing: border-box;
  box-shadow: 2px 2px 4px #00c9c9;
 }

p{
  margin: 0px;
  text-align: center;
  padding: 10px 0px;
  font-size: 18px;
 }

.buttons{
  text-align: center;
 }

button{
  background-color: #FFB40F;
  border: none;
  color: white;
  padding: 10px 15px;
  margin: 10px 15px;
  text-align: center;
  border-radius: 4px;
  font-size: 14px;
 }

 

About

Jr. Software developer, Skilled in frontend technologies like React and Angular | Backend technologies like node and Express | SQL and NoSql Database.

Get notified on our new articles

Subscribe to get the latest on Node.js, Angular, Blockchain and more. We never spam!
First Name:
Email:

Leave a Comment