Functional Components vs. Class Components in React

The main differences, when to choose one over the other, and why you should know both

Gianmarco Ebeling
Better Programming

--

React logo in space
Photo from Wallpaper Cave.

React is a JavaScript library created by Facebook. It uses a declarative approach and simplifies the creation of user interfaces. A web application built in React is structured in several small and isolated pieces of code called React components. There are two main types of components:

  • Functional components
  • Class components

This article will help you understand the differences, when to choose one over the other, and why you should know both.

A Leap Into the Past

To understand the differences, it’s important to know what the React ecosystem used to be like. Years ago, functional components were used only to render JSX to show content to the user. On the other hand, class components were also able to utilize the lifecycle method system or the state system.

Diagram comparing how functional and class components used to be
How the React ecosystem used to be.

In February 2019, the React team introduced Hooks as a new addition to React v16.8.0. React Hooks gave functional components the same capabilities as class components, with the possibility to use the state system and achieve the same results as the class components’ lifecycle methods.

Diagram comparing functional and class components today
The React ecosystem today.

Let’s now analyze the main differences.

1. Rendering JSX to Show Content

JSX stands for JavaScript XML. As explained by W3Schools, it “allows us to write HTML elements in JavaScript and place them in the DOM without using any createElement() and/or appendChild() methods.”

Rendering JSX in a class component

Class components are ES6 classes that extend the rendering method of React.Component:

You can also achieve the same result using destructuring:

Rendering JSX in a functional component

Functional components are JavaScript functions that return JSX:

2. Handling State

With the state system, we create a JavaScript object containing some data strictly relevant to the component we’re working on. Before Hooks, the state system was only usable with class components. But with this new addition, it is now possible to obtain the same result with functional components.

To better see the differences between the two components, let’s make a simple counter that starts from zero and increments by clicking on the + button.

Handling state in a class component

In a class component, we initialize our state object at the top containing a property called count and set it to 0. We reference our piece of state inside the render method with this.state.count. Finally, we call an arrow function that changes the state of count with this.setState whenever a user clicks on +.

Handling state in a functional component

In a functional component, first, we have to get the useState function from the React library. Then, we make use of array destructuring to initialize a new piece of state. The first variable inside the count array is the piece of state that we are trying to keep track of, while the second element (setCount) is a function that we call to update our piece of state. useState takes in one argument that is the default value for our piece of state. Finally, we call an arrow function that changes the state of count with the use of setCount whenever a user clicks on +.

3. Passing Props

To pass data as parameters from one React component to another, we use React’s props.

Passing props in a class component

In a class component, props are received via the use of this.

Passing props in a functional component

In a functional component, we are passing props as an argument of the function.

4. Lifecycle Method System

Every component in React goes through a lifecycle of events. Lifecycles have a significant role in the timing of rendering. An example of a lifecycle method is the componentDidMount() that corresponds to the useEffect() method in a functional component.

componentDidMount() in a class component

componentDidMount is a lifecycle method that is called after the component gets mounted on the DOM.

useEffect() in a functional component

To obtain the same result in a functional component, we use the useEffect hook with the second argument of [].

Functional or Class Components?

In this article, we noticed that class components and functional components today have the same capabilities. This leads to an important question: “Which one should we learn and use?”

The answer is simple: both!

Suppose you are working with a company that has already been using React for a while. Chances are that they are making use of class-based components because that used to be the only way that we could work with the state system and lifecycle methods.

On the other hand, any company that is working on a newer project might be making use of either class components or functional components.

Understanding both approaches will help us to identify which one to use in any given situation.

--

--

Founder of Deutsch Mentor. Indie Maker. Building a portfolio of SaaS to achieve financial freedom. Just ship it!