Understanding the Difference Between Function & Class Components in React
Tags: Web Development, React, JavaScript, App Development, Programming

Understanding the Difference Between Function & Class Components in React

Using components in React with a better understanding of how they affect your App’s Performance has always been a confusing topic, and developers end up having a bulky code base that gets harder to manage through time. So, the major answer that you will hear that Class Components provide access to more features like (state), but with Hooks that not valid anymore.

You must have heard about one of them having better performance, but performance depends on what the code is doing rather than choosing a class or function. The performance is almost the same and can make differences using various optimization techniques.

Function Components

Consider A Component. Let’s take an example using a simple component that simulates a network request with setTimeout and shows a confirmation alert. If props.user is ‘Mohit’ it will simply show ‘Followed Mohit’ after 3 seconds.

In the example above you can use arrows or function declaration both work the same way.

Implementing the above example in class:

Oftentimes people mistakenly look at both the same way, but there is a difference between their implications. To observe the difference you can open the code sandbox I have created for a better understanding.

Open the code sandbox given above and run the code, now try these steps to measure the difference.

Click on the follow button. (function or class you can choose any of it) Change the selected profile before 3 seconds pass. Now read the text alert.

You will notice when we click on the follow button (using a function component) and then switch to a different profile, it shows the previous user name instead of what we selected later 3 seconds pass. But when we press the follow button( using a class component), it shows the newly selected user name every time. You will getter a better understanding by running the sandbox on your own.

In this example, if you press the follow button on ‘Mohit’s’ profile and then change the selected user you are still going to see Mohit in the alert dialogue box in case of function component. And in the case of the class component, you will notice the switched profile name in the alert dialogue box.

As you can see, the first behavior is totally what we claim to be correct for us, as my component shouldn't get confused about who I followed!.

So what can be the reason for this buggy behavior?

To understand this let us take a closer look at the showMessage method in our class.

The class method reads from this.prop.user and props are immutable in React so they can never change, but this has always been mutable & that’s the whole purpose of this in a class as React mutates it over in render and lifecycle method so that we can the fresh version in the render. If our component re-renders while already being in the process, this.props will change & the showMessage method reads the user from ‘too new ‘ props.

This shows an interesting relationship in the nature of User Interfaces, and if we say UI is a function of the current application state, the event handlers are a part of the render result. But scheduling a timeout that reads this.props breaks the relation.

So let’s say there is no such thing as function components, what would be the solution to this problem then?

If we want to somehow ‘repair’ the connection between render and correct props and the showMesage callback which reads them. One way we can achieve this possibility is by reading this.props early during the event and then pass them through the timeout completion handler. Still, this approach will make the code more error-prone at the end, and we can’t use more than one prop and also we can't access the state & we will end up having the same problems again.

Even if we put the alert code inside handleClick won't answer the bigger problems. The aim is to structure our code in such a way that allows splitting it into more methods and also being able to read the props and state corresponding to the render related to that call.

What if we bind the methods in the constructor?

Remember that the problem is in reading this.props too late, not with the syntax we are using, so it won’t solve this problem. Bit problem can be solved if we rely on JavaScript closures. However, closures are avoided as it is hard to think about a value that can be mutated overtime. So if we use closures over props or state from a particular render, we easily can count on them.

Function components capture the rendered values:

But what the point of having a class if we are defining the functions inside render.

When the parent component renders the ProfilePage with different props, React calls the ProfilePage function again & the event handle that we already clicked which belongs to the previous render having its own user value is being read by showMessage. And that’s why in the above sandbox example when we click on follow Mohit after changing the selected user it still shows ‘Followed Mohit’.