Deciding between Class and Functional Components

Sara Bastian
3 min readDec 29, 2020

In the midst of creating my first React project, I find myself continually facing the same decision with each UI feature I build out — should I make this a class component or functional component? My default up until this point has been the class component, should I need to create a state or implement a lifecycle method along the way, but I keep wondering, shouldn’t I be more intentional with this decision? Of course that question was rhetorical, so I wanted to dig deeper to understand the when and why of choosing a functional over class component, or vice versa.

First, let’s define each. A functional component (as the name implies) is a Javascript function that accepts props as an argument, which gets passed down from its parent component, and returns JSX.

Functional Component:

These can be thought of as pure functions, as they always behave the same (with the same props).

A class component is a Javascript class, which must extend React.Component and include a render() method, as well as return (placed within the render), which consists of JSX. You will also need to import React at the top of the file, as the below example demonstrates:

Class Component:

Since this is a class, you will need a this in front of props each time you implement props, or state.

I mostly default to class components in the event I want to add state at some point. However, due to my new understanding, this mentality is slightly flawed, since functional components can actually also be stateful. Until recently, defining and handling state was only possible in a class component, but with React 16.8 and the introduction of React Hooks (and in particular the useState Hook), functional components can now handle state as well.

Defined in the array, count and setCount can be thought of as the state and the setter (the function that will change the state). The useState hook takes an argument of an initial state that will change on every click event.

So, what about lifecycle methods, the other main usage / rationale I had for implementing a class component over a functional one? Hooks also make lifecycle possible as well. The main lifecycle method I have been using thus far is componentDidMount to handle fetching from my Rails API. In a functional component, we would use the useEffect Hook to replace that method and handle timing of rendering.

There is a way to fetch data from an api with useEffect and other React Hooks, but for the purposes of this post I provided a simpler example. Refer to this post if you want to understand how.

The function passed to the useEffect hook is our effect, and each time React renders this component, it will remember and run our effect after updating the DOM.

useEffect Hook will also apply to componentDidUpdate and componentWillUnmount, however note a significant difference between useEffect and componentDidUpdate and componentDidMount — effects run through useEffect will not stop the browser from updating the screen, and will not happen synchronously.

So then, since both of my scenarios for using a class component over a functional component have been debunked as both can handle state and lifecycle methods, how do we know when to use one over the other?

It’s not always black and white, but here are some quick go-to recommendations/suggestions gleaned from various react resources:

- Try to use stateless functions, or functional components, whenever possible

- Go with functional components and hooks when your component only needs to accept props and render JSX

- Go for class component when data fetching, as data fetching with useEffect hooks is not as natural as it is with lifecycle methods.

Resources:

https://stackoverflow.com/questions/36097965/when-to-use-es6-class-based-react-components-vs-functional-es6-react-components

https://stackoverflow.com/questions/53062732/react-function-components-with-hooks-vs-class-components

https://www.twilio.com/blog/react-choose-functional-components

--

--

Sara Bastian

full-stack developer exploring how software can solve real-world problems | https://sarabastian.com/