Recently functional components are becoming more and more popular, so why is that?
This article will help you understand the differences between functional and class components by walking through each one with sample code so that you can dive into the world of modern React!
React.Component which has a render method. A bit confusing? Let’s take a look into a simple example.
As you can see, a functional component is a function that returns JSX. If you are not familiar with arrow functions introduced in ES6, you can also check out the example below without.
On the other hand, when defining a class component, you have to make a class that extends
React.Component. The JSX to render will be returned inside the render method.
Below is the same example but without using destructuring. If you are not familiar with destructuring, you can learn more about and introduced in ES6!
Passing props can be confusing, but let’s see how they are written in both class and functional components. Let’s say we are passing props of the name “Shiori” like below.
Inside a functional component, we are passing props as an argument of the function. Note that we are using destructuring here. Alternatively, we can write it without as well.
In this case, you have to use
props.name instead of name.
Since it is a class, you need to use
this to refer to props. And of course, we can use destructuring to get
name inside props while utilizing class-based components.
Now we all know that we cannot avoid dealing with state variables in a React project. Handling state was only doable in a class component until recently, but from React 16.8, React Hookwas introduced to allow developers to write stateful functional components. You can learn more about Hooks from . Here we are going to make a simple counter that starts from 0, and one click on button will increment the count by 1.
Handling state in functional components
To use state variables in a functional component, we need to use
useState Hook, which takes an argument of initial state. In this case we start with 0 clicks so the initial state of count will be 0.
Of course you can have more variety of initial state including
string, or even
useState returns the current state and a function that updates it, we are destructuring the array like this. If you are a bit confused about the two elements of the array, you can consider them as a state and its setter. In this example we named them
setCount to make it easy to understand the connection between the two.
Handling state in class components
The idea is still the same but a class component handles state a bit differently. Firstly, we need to understand the importance of the
React.Component constructor. Here is the definition from the :
“The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.”
Basically, without implementing the constructor and calling super(props), all the state variables that you are trying to use will be undefined. So let’s define the constructor first. Inside the constructor, you will make a state object with a state key and initial value. And inside JSX, we use
this.state.count to access the value of the state key we defined in the constructor to display the count. Setter is pretty much the same, just different syntax.
Alternatively, you can write an
onClick function. Remember, the
setState function takes argument(s) of state, props(optional) if needed.
Finally, let’s talk about lifecycles. Hang on, we are almost there! As you already know, lifecycles play an important role in the timing of rendering. For those of you who are migrating from class components to functional components, you must be wondering what could replace lifecycle methods such as
componentDidMount() in a class component. And yes, there is a hook that works perfectly for the purpose, let’s check it out!
On Mounting (componentDidMount)
The lifecycle method
componentDidMount is called right after the first render completes. There used to be a
componentWillMount that happens before the first render, but it is considered legacy and not recommended to use in newer versions of React.
componentDidMount, We use the
useEffect hook with the second argument of
. The second argument of the
useState hook is normally an array of a state(s) that changes, and
useEffect will be only called on these selected changes. But when it’s an empty array like this example, it will be called once on mounting. This is a perfect replacement for a
Basically the same thing happens here:
componentDidMount is a lifecycle method that is called once after the first render.
On Unmounting (componentWillUnmount)
I am happy to tell you that we can also use a
useState hook for unmounting as well. But be careful, the syntax is a bit different. What you need to do is return a function that runs on unmounting inside the
useEffect function. This is especially useful when you have to clean up the subscriptions such as a
clearInterval function, otherwise it can cause a severe memory leak on a bigger project. One advantage of using
useEffect is that we can write functions for both mounting and unmounting in the same place.
There are pros and cons in both styles but I would like to conclude that functional components are taking over modern React in the foreseeable future.
As we noticed in the examples, a functional component is written shorter and simpler, which makes it easier to develop, understand, and test. Class components can also be confusing with so many uses of
this. Using functional components can easily avoid this kind of mess and keep everything clean.
It should also be noted that the React team is supporting more React hooks for functional components that replace or even improve upon class components. To follow up, the React team mentioned in earlier days that
useEffect while also promising . The team is seeking to in newer cases, which means that there is no need to switch over the existing projects that utilize class components to the entire rewrite with functional components so that they can remain consistent.
Again, there are a lot of valid coding styles in React. Yet I prefer using functional components over class components for those reasons listed above. I hope this article helped you get more familiar with modern React. To learn more, check out