A Journey from Class to Function in React

Components are the core parts of a React application. They are the software units that build our application. But wait, Function or Class component? Which one to pick?

This was the first question I had when I started to do my first React project at work. I know this is an easy pick for some people: of course function component!

However, for me – and many like me – this was not obvious. The reason was the past.

When I started to learn computer science and programming as an 18-year-old, Object Oriented Programming (OOP) was my way in. I started coding with this idea in my mind that Everything in this world is an instance of some class. Chicken, Car, Dog, The Earth, you name it.

I mean, everything is an Entity with some properties and methods. So Class it is.

So from the very beginning Class was a first-level citizen in my mind. On each code, I was looking for some pattern to define a Blueprint as a class. Yeah, I was a bit fanatic in my way.

Naturally, I picked the Class component for the React application.

But sometimes your favorite thing in the world becomes your burden!

When I started the code, was like a Dream! I was tired of Vanilla JS and JQuery for front-end development! React and Classes helped me to code the front-end like the back-end that I was used to! Nice Job!

My old friends were there again. Class, Properties (states), and methods!

But, gradually I lost my hope in the Class component and started the transition to Function One.

Why did I change my mind

Before I start, I implemented a class component where users can:

  • Generate a public ID
  • increase counter
  • Generate an internal ID

By clicking buttons. The code is here: https://github.com/Pooya-Oladazimi/blog-post-app/blob/main/src/components/classComponentExample.jsx

You can run the React app and navigate to http://localhost:3000/classExample

I also implemented the equivalent component with function: https://github.com/Pooya-Oladazimi/blog-post-app/blob/main/src/components/functionComponentExmple.jsx

Route: http://localhost:3000/functionExample

Now let me tell you why I changed from my sweet class to function.

Less Code

That’s the first thing I noticed. It started when I felt some of the code parts that you have to do in a class component are unnecessary.

For example, if a class method wants to use the “this” reference to a class object, you need to bind it in the constructor.

Besides, the constructor itself and the state setting take some lines. You also need to define a render() function every time you want to return something.

Look at the class constructor:

constructor(props){
        super(props);
        this.state = ({
            counter: 0,
            id: null,
            internalId: ''
        });
        this.increaseCounter = this.increaseCounter.bind(this);
        this.setNewId = this.setNewId.bind(this);
        this.setInternalId = this.setInternalId.bind(this);
}

We have only three methods here. Imagine you have a more complex class with a high number of methods.

Equivalent for a function component:

const [counter, setCounter] = useState(0);
const [id, setId] = useState(null);
const [internalId, setInternalId] = useState('');

No need to bind anything or wrap things up in a constructor!

Also, less code shows itself even in one line. Imagine you want to access a class state:

{this.state.counter}

In a function component:

{counter}

Less code is always better!

Mistake in the set-state

This happened to me a couple of times and boy oh boy! what a nightmare!

Let’s say we have this initial state in our class component:

this.state = ({
   id: null
});

Now down there in the code, you update the state, but make a typo in the variable name:

this.setState({
  Id: 22
});

In this case, React sets a new state var named Id. and now you have two IDs: id and Id

This cannot happen in a function component. The reason is, in a function component, you need to declare a setter function for your state:

const [id, setId] = useState(null);

You have only one way to change the state var and it is by calling setId() function. Much better!

Re-render on state/prop change

I can say that this is the most important reason for changing my mind from class to function.

In a class component, every time an input prop or state var changes, it triggers a component re-render.

As a result, you will end up with many unneeded re-rendering that can affect your app performance.

Note: You can prevent an update in class but you need to implement a mechanism yourself. (See below)

But in a function component, you can easily control the re-render.

Function components utilize the useEffect hook. In these hooks, you can have some dependencies to tell only re-render when a certain variable changes.

useEffect(() => {
   // after update code only when id changes
}, [id]);

But in class one, you need to come up with some extra work. Roughly like:

componentDidUpdate(prevProps, prevState) {
  if (this.state.id !== prevState.id) {
     // after update code only when id changes
  }
}

So basically, you need to keep track of the changes to prevent updates. Challenging when you have a high number of state vars and input props!

Inside our example React app, just click the New Internal ID button on both components and compare the console.log(‘updated!’) outcome in your browser console!

Function is also Class!

In the end, I have to say that Functions in React are also Classes! (I know they are not but don’t be too critical). Sounds weird but if you love OOP, you do not miss that much! You can still see them as objects with some properties and methods!

Thank you for reading my journey!

The End.