React: Reduce stateful components

Posted on July 4th 2020 in React by Pim Debaere.

React: Reduce stateful components

In a previous blog post I announced that I soon would be posting more best practices to take into account when developing a React app. Today I write about the difference between stateful and stateless components.

Stateful and stateless

A stateful component is nothing more and nothing less than a component using the state variable. In earlier versions, you could only use stateful components when you wanted to change the component's data, in other words, when you wanted to use a lifecycle method like componentDidMount() and componentDidUpdate() (cfr. "The Component Lifecycle").

If the component didn't need any changes to the given data, you could stick with props. Do note that, unlike state, you can't modify props once passed to a component. We call a component without state stateless or, more commonly used, functional.

Meet the Hooks

From version 16.8 we can use React Hooks. These let us use [state] even in stateless, or functional, components. These Hooks can also be used to replace lifecycle methods. If that's not a stroke of luck!

Why is this so interesting? Stateless, or functional, components generally give better performance. This is easy to explain since there is no state here and no lifecycle methods are taken into account. In other words, there is less code to run in the background. This loss of performance is usually negligible and hardly noticeable on smaller projects. But every little bit counts, so get into the habit of writing as many functional components as possible.

This is not only an improvement in performance, but also in legibility – and therefore maintainability. For example, a functional component contains fewer lines of code compared to a stateful component that does exactly the same.

Below is an example of both.

1
2
3
4
5
6
7
8
9
10
11
12
// stateful component
class InputText extends React.Component {
    handleChange = () => {
        // some logic that needs to be executed
    }
    
    render() {
        return (
            <input type="text" onChange={this.handleChange} />
        )
    }
}
Fig. 1 – Example of a stateful component.
1
2
3
4
5
6
7
8
9
10
// stateless, or functional, component
const InputText = () => {
    const handleChange = () => {
        // some logic that needs to be executed
    }
    
    return (
        <input type="text" onChange={this.handleChange} />
    )
}
Fig. 2 – Example of a stateless of functional component.

In a next post I will go deeper into the use of Hooks. Stay tuned!