Function vs Class Components in React

You might be going through React tutorials and some are using classes and others are using functions. Or you’re taking a udemy course or reading a book on React that leave hooks for the last chapters. All this naturally that leaves you wondering, which is more important for me to learn, hooks or classes ? Which should you be using in your project? Is it still worth it to learn about classes and their lifecycle methods? Why do both exist and which one is better? Do you have a choice ?

TL;DR - use functional components when you build new components. Refactor the class components to function components when you have time or you’re fixing bugs in them.

There’s no need for you to know more than only that, but if you’re curious, read further.

At the time I’m writing this, there are 2 years since React 16.8 was released, including hooks! And even longer since it got introduced. The shift has taken some time but today the React community has adapted to these changes. The majority of the most popular libraries are now using hooks: formik, react-query, react-router etc. The best practices of hooks have found their way into the tutorials and they’ve become mature enough that you don’t have to worry about going full hooks.

Code examples

Here we have two versions of the same component using class lifecycles vs hooks. This clock code is taken from React’s docs. Just leaving this here in case you’d like to visualize the differences

class component:

class Clock extends React.Component {
  constructor(props) {
    super(props)
    this.state = { date: new Date() }
  }

  componentDidMount() {
    this.timerID = setInterval(() => this.tick(), 1000)
  }

  componentWillUnmount() {
    clearInterval(this.timerID)
  }

  tick() {
    this.setState({
      date: new Date(),
    })
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    )
  }
}

function component:

import { useState, useEffect } from "react"

function Clock() {
  const [date, setDate] = useState(new Date())

  useEffect(() => {
    var timerID = setInterval(() => tick(), 1000)

    return function cleanup() {
      clearInterval(timerID)
    }
  })

  function tick() {
    setDate(new Date())
  }

  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {date.toLocaleTimeString()}.</h2>
    </div>
  )
}

and function component could also be written with an arrow function like this

const Clock = () => {
  // some code
  return <div>...</div>
}

How was this “back in the days” ?

There’s no wonder why it isn’t very clear whether you should be using functions or classes. Before hooks got released, people were still using class components but they were also using function components. The big difference was that function components couldn’t hold state nor side effects. If you wanted to add some state or side effects you had to use a class component. Some were tired of having to refactor their function components into class components every time they wanted the component to be stateful, so they just stuck with using class components everywhere in case they’d later have to add a state. With the arrival of hooks you can have both state and side effects in function components. And you can’t use hooks inside class components.

What advantages have hooks over classes ?

Let’s compare function components and hooks and class components and lifecycle methods. I actually don’t know about any technical advantage of using classes rather than functions in react. Usually when somebody says something like “with lifecycles you had finer control”, “class components are more readable” or “you had inheritance with classes”, it’s very probable that they haven’t used hooks a lot. Even if there was some edge case where classes were better than hooks, hooks are going to be the future in React and classes are not.

There’s really no need for you to know about all the advantages of function components and hooks but if you have this situation that you’re trying to convince someone, here are some points:

  • there’s no “this”

When using functions you don’t have to understand “this” which can often be pretty confusing. Because it’s confusing it can lead to errors and requires you to remember that “this” is mutable and therefore this.props and this.state is mutable. Here’s a great article from Dan Abramov that explains it in more details.

  • encourages code reuse

Today it’s so much easier to share states and side effects, which means much less boilerplate and nicer developer’s experience. Like they say in the docs : “Hooks allow you to reuse stateful logic without changing your component hierarchy.” And as this means less boilerplate, that means better readability. Of course the level of readability is arguable and pretty personal, but I still think that those that have gotten used to hooks would agree with me.

  • reduces spagehetti code

Before with the lifecycle methods, related code sometimes got split into two methods and unrelated logic often colocated in same method. Hooks allow you to organize related code in the same place.

  • nicer developer’s experience:

Before if you wanted to reuse your side effects, you had to restructure your components. You had to make a higher order component or use render props.
Same if you had a function component and you wanted to add a state to it, you then had to transform it into class components. Hot reloading also was not working as well with classes.

  • hooks are the future

Whether we like it or not, classes will without a doubt become deprecated at some point in the future. Even though the React team says that they’ll continue to support them for foreseeable future, that will surely change at some point.


There are surely some other advantages like “no more method binding”, “useContext allows you to read the context without the consumer”, “the useReducer hook” etc.. but those above are the most important ones in my opinion.

Are there times that you still need classes ?

There are times that you still need classes, but most often you don’t have to have a deep knowledge on how they work. Error boundaries can only be used in classes because it’s using the lifecycle method getDerivedStateFromError. But you can avoid writing and maintaining a class component yourself, by using react-error-boundary

There’s also another lifecycle method that doesn’t have an equal in hooks. It’s called “getSnapshotBeforeUpdate” and it’s unlikely you’ll have to use it. It didn’t even become a part of React until version 16.3 in 2018. The most common use case for it is when you’re making a chat messenger. If you need it you could just create one class component or you could implement it yourself using hooks, instead of getting it ready-made, handed on a sliver platter with classes.

Why do some people still want to use classes ?

It takes time and effort to learn new things and also to refactor existing code. The whole team has to upgrade their knowledge and go through a mental shift using hooks. Some people prefer using just one way of doing things because they find it complicates things to have both classes and function hooks components. There’s no urgent need for them to refactor right now as React states they’ll support classes for foreseeable future.

I’ve occasionally seen that some people are against hooks because of useEffect. That hook is sometimes quite tricky because if you don’t handle it correctly it can result too many rerenders or even an infinite loop. But that’s just something that will come with practice and patience. I’ve a friend freelancing for a manager and the whole company didn’t want to write new components using hooks. When asked why they just said that they were used to classes. I guess they’re shooting themselves a bit in the foot in the longterm.

Do you have to learn about lifecycle methods and hooks?

Well all knowledge is good knowledge but time is limited so how much time should you spend on classes & lifecycle methods? It can be helpful to learn classes because you might work in a codebase that still uses classes. In that case I’d only learn just enough about them to be able to refactor them into function components.

Might somebody ask you an interview question about class components ? Yes, could happen. Not the best interview question in my opinion unless you’re hiring somebody to upgrade all your classes to functional components. If you started learning React in 2019 and you’d get that question, you kind of have an excuse not being a class expert and you can just say that you’re willing to learn. If you’re not new to React, you might have forgotten some details about them as you might not have used them for quite some time now.

Has that something to do with Redux vs context ?

No not really. But what makes us think that? Context existed actually before hooks came out but wasn’t used as much as today, mostly because the react docs told you to avoid them. Then version 16.3 of React came out with a new syntax for context which was much nicer and it looked as if context could handle all of your app’s state…which it does, until your app gets bigger and the state management gets more complicated. At that point you can start to experience some performance problems. You can get pretty far with it but it does not really replace Redux. You don’t necessarily need Redux either, there are lots of other ways to manage the state of your app. You could also use context, until your app gets big and then use context in combination with jotai. But choosing your app management library is the subject of a whole another looong article!

Summary

I hope this article has cleared up some of your confusion. Just use hooks and functions every time you write a new component. If you’re working with class components, and you have time, refactor them. Especially if you’re already refactoring them or fixing bugs in them, just as recommended in React’s docs. That way your code base will probably naturally get upgraded to hooks with time before React will potentially in far-away future deprecate classes.

More on this :

https://reactjs.org/docs/hooks-intro.html#gradual-adoption-strategy

https://reactjs.org/docs/hooks-faq.html#adoption-strategy


Get more tips in my almost monthly newsletter about CSS & React!