React hooks vs Classes

February 20, 2019

A post by Will Mayger
Twitter . Instagram

With the new react hooks just released in version 16.8 of react, most people are now experiencing a little fight or flight.

Do I start with react hooks? Is it safe? Is it stable? How long will it take to change the code? React hooks vs Classes? What’s better?

I will try my best to break them down a little in this post about react hooks vs classes!

Well, whilst all of these questions are valid, it’s also over-thinking it too much. There is no immediate rush to use react hooks if you don’t want to. Classes still work well, are reliable, and they aren’t going anywhere.

With this being said I highly recommend that you start learning a little bit about react hooks so you can start using it in some of your future projects if you decide that you like it!

Mix and match

One of the first things to remember is that you are not limited to using hooks for your entire project, you can actually mix and match where you want.

On a similar note, it’s pretty easy to convert react hooks into classes and vise versa if you do ever want to convert one to the other! This means it is incredibly easy going and puts absolutely no pressure on you to use them or not.

Comparison

Let’s start by comparing the differences between react hooks vs classes.

Here is a simple react component using classes that you might recognize:

import React from 'react';

export default class ReactHooksVsClasses extends React.Component {
    state = {
        count: 0,
    }

    componentDidMount() {
        window.addEventListener('resize', this.resizeEvent);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.resizeEvent);
    }

    resizeEvent = () => {
        this.setState(state => ({
            count: state.count + 1,
        }));
    }

    render() {
        const {
          count,
        } = this.state;

        let resizeString = 'This has never been resized';

        if (count === 1) {
            resizeString = 'This has been resized once';
        } else if (count > 1) {
            resizeString = `This has been resized ${count} times`;
        }

        return (
            <h1>
                {resizeString}
            </h1>
        );
    }
}

Nothing to crazy is going on here with our class version, when the component is mounted, we initialize a new event listener when the user resizes the page and display the amount of times the page has resized. When the component gets unmounted it then removes the event listener.

Generally speaking you probably won’t need to use addEventListener in React, but for the purposes of this example, we will.

Here is the equivalent using react hooks:

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

export default function ReactHooksVsClasses() {
  const [count, setCount] = useState(0);

  const resizeEvent = () => setCount(count + 1);

  useEffect(() => {
    window.addEventListener('resize', resizeEvent);

    return function cleanup() {
      window.removeEventListener('resize', resizeEvent);
    }
  });

  let resizeString = 'This has never been resized';
  if (count === 1) {
    resizeString = 'This has been resized once';
  } else if (count > 1) {
    resizeString = `This has been resized ${count} times`;
  }

  return (
    <h1>
      {resizeString}
    </h1>
  );
}

Both implementations are doing exactly the same thing, and I think you can probably already see a huge benefit of react hooks just by looking at both pieces of code.

The react hooks implementation is much smaller than the version making use of classes. This means higher levels of maintainability because of having better clarity over the code.

Aside from the size difference, you have probably noticed that there are an extra two functions being imported.

One called useState and the other useEffect.

Simply put, the useEffect function will be handling your lifecycle events in react hooks such as, componentDidMount, componentDidUpdate, componentWillUnmount.

It is basically all of these combined into one.

So any code that you would have included into one of these life cycles you can now do in here.

The useState function is effectively replacing your state object and giving you a getter (kind of) and setter instead. It’s not actually a getter because it gives you the variable directly instead of in the form of a function call.

You can access the react hooks useState properties and methods by using array destructuring which is just surrounding the variables you are declaring in square brackets (const [...] = ...).

Let’s break this down a little more, you can think of it like this: const [getter, setter] = useState(0); where getter is actually a variable with the current state value, in this instance it would be 0 because we defined it by passing 0 into the function as an argument.

And the setter is a function you will call to update the state, for example setter(getter + 1); in this scenario.

Finally, there is another function in the react hook version which looks like a closure, it has the name cleanup, this is the equivalent of componentWillUnmount, so any clean up upon unmounting you will need to do here. If you do not need to do any, you don’t actually need to return this clean up function at all.

In conclusion of react hooks vs classes.

Performance

While there does not seem to be a huge performance boost with react hooks, there definitely seems to be a few benefits for it.

The first, and main, performance boost is that when you use react hooks, you won’t be using a class.

Classes are pretty heavy when it comes to performance, and without them it removes a lot of the overhead and code that comes with classes.

See more about this in detail here in the official react docs.

Maintenance

I already love React but not everyone does. Hopefully more and more people will start to love it now in my opinion, React is going to get much simpler, easy to use and the code base of most projects will now shrink meaning more people will warm to it.

I know a lot of people who love the idea of React in general but tend to shy away because they think it seems quite complicated or messy. Now it is starting to look simple and easy to follow along with react code even without too much knowledge of React itself.

This coupled with the noticeable size difference will make it way more maintainable than it ever has been!

“Under the hood”

Whilst it is not always needed to understand what happens behind the scenes, I would recommend doing so before diving into react hooks because its a very short read and will prevent a fair amount of debugging.

An example would be that you should never wrap a useEffect hook in a conditional statement because this could prevent the hook from being called.

This is a problem because React relies on the order in which Hooks are called to produce the expected outcome.

So when you wrap a hook in a conditional it might not be called meaning the order would no longer be correct.

Instead use your conditional statement within the react hook.

More about this here: Official react hook rules

Finally

It is down to personal preference at the end of the day, there are a lot of benefits for using react hooks over classes but it is for you to decide if it is best on a project to project basis when it comes to react hooks vs classes.

I know that for me, I will be trying to implement them where I can in my future projects as I absolutely love the idea of react hooks. I tried them out in there alpha stages and I will continue in there official release.

I hope this post has some what helped you out in deciding between react hooks vs classes. Here is the link to the full, official, documentation for react hooks if you want to go ahead and start learning.

I would love to hear your opinions down below in the comments.

Thanks, Will