Article image Functional vs Class Components

7. Functional vs Class Components

Page 22 | Listen in audio

When embarking on a journey to learn React, one of the fundamental concepts you'll encounter is the distinction between functional and class components. Both types of components serve the same purpose: they allow you to create reusable pieces of UI. However, they do so in different ways, and understanding these differences is crucial for any React developer. In this section, we'll delve into the characteristics, advantages, and use cases of functional and class components, helping you decide which to use in your projects.

Introduction to React Components

React components are the building blocks of any React application. They allow developers to split the UI into independent, reusable pieces, making it easier to manage and maintain. Components can be thought of as JavaScript functions or classes that accept inputs, called "props," and return React elements that describe what should appear on the screen.

Functional Components

Functional components are the simplest form of React components. They are JavaScript functions that receive props as an argument and return a React element. Here's a basic example of a functional component:


function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

Functional components are often referred to as "stateless" components because they do not manage their own state. However, with the introduction of React Hooks in version 16.8, functional components can now manage state and side effects, making them just as powerful as class components.

Class Components

Class components are more feature-rich than functional components. They are ES6 classes that extend from React.Component and have access to additional features such as local state and lifecycle methods. Here's an example of a class component:


class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

Class components have been the traditional way to manage state and lifecycle methods in React. However, they come with more boilerplate code compared to functional components.

State Management

One of the key differences between functional and class components lies in how they manage state.

Functional Components with Hooks

Before Hooks, functional components were limited to rendering UI based on props. However, with the introduction of Hooks, functional components can now manage their own state using the useState Hook:


import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

The useState Hook allows you to add state to functional components, making them just as capable as class components in terms of state management.

Class Components

In class components, state is managed using the this.state object and updated with this.setState():


class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

While class components provide a clear structure for managing state, they often require more boilerplate code compared to functional components with Hooks.

Lifecycle Methods

Another significant difference between functional and class components is how they handle lifecycle events.

Functional Components with Hooks

Functional components handle lifecycle events using the useEffect Hook. This Hook allows you to perform side effects in your components, such as fetching data or subscribing to events:


import React, { useState, useEffect } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []); // The empty array ensures this effect runs only once

  return <div>{data ? JSON.stringify(data) : 'Loading...' }</div>;
}

The useEffect Hook replaces the need for lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount in class components.

Class Components

Class components use lifecycle methods to perform side effects. These methods are part of the React.Component class and include:

  • componentDidMount: Invoked immediately after a component is mounted.
  • componentDidUpdate: Invoked immediately after updating occurs.
  • componentWillUnmount: Invoked immediately before a component is unmounted and destroyed.

Here's an example of a class component using lifecycle methods:


class DataFetcher extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: null };
  }

  componentDidMount() {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => this.setState({ data }));
  }

  render() {
    return <div>{this.state.data ? JSON.stringify(this.state.data) : 'Loading...' }</div>;
  }
}

While lifecycle methods provide a clear structure for managing side effects, they can sometimes lead to repetitive code, especially when handling multiple lifecycle events.

Performance Considerations

Performance is another factor to consider when choosing between functional and class components. Functional components are generally easier to optimize because they do not have the overhead of the this keyword and lifecycle methods. Additionally, React's useCallback and useMemo Hooks can be used to optimize functional components by memoizing values and functions.

Class components, on the other hand, can benefit from shouldComponentUpdate and PureComponent to prevent unnecessary re-renders. However, these optimizations require more boilerplate code compared to the Hooks available in functional components.

Readability and Simplicity

Functional components tend to be more concise and easier to read due to their simpler syntax and the use of Hooks. They also encourage developers to break down complex components into smaller, reusable pieces, improving code organization and maintainability.

Class components, while more verbose, can be easier to understand for developers familiar with object-oriented programming. They provide a clear structure for managing state and lifecycle events, which can be beneficial for larger, more complex components.

Conclusion

Both functional and class components have their advantages and use cases. Functional components, with the addition of Hooks, offer a modern, concise way to manage state and side effects, making them a popular choice for new React applications. Class components, while more verbose, provide a familiar structure for developers coming from an object-oriented background and can be beneficial for larger, more complex components.

Ultimately, the choice between functional and class components depends on your specific needs and preferences. As React continues to evolve, it's likely that functional components will become the standard, but understanding both types of components will make you a more versatile and capable React developer.

Now answer the exercise about the content:

What is one of the fundamental concepts encountered when learning React, as mentioned in the text?

You are right! Congratulations, now go to the next page

You missed! Try again.

Article image Props: Passing Data Between Components

Next page of the Free Ebook:

23Props: Passing Data Between Components

9 minutes

Earn your Certificate for this Course for Free! by downloading the Cursa app and reading the ebook there. Available on Google Play or App Store!

Get it on Google Play Get it on App Store

+ 6.5 million
students

Free and Valid
Certificate with QR Code

48 thousand free
exercises

4.8/5 rating in
app stores

Free courses in
video, audio and text