When to use ES6 class based React components vs. functional ES6 React components?
Solution 1
New Answer: Much of the below was true, until the introduction of React Hooks.
-
componentDidUpdate
can be replicated withuseEffect(fn)
, wherefn
is the function to run upon rerendering. -
componentDidMount
methods can be replicated withuseEffect(fn, [])
, wherefn
is the function to run upon rerendering, and[]
is an array of objects for which the component will rerender, if and only if at least one has changed value since the previous render. As there are none,useEffect()
runs once, on first mount. -
state
can be replicated withuseState()
, whose return value can be destructured to a reference of the state and a function that can set the state (i.e.,const [state, setState] = useState(initState)
). An example might explain this more clearly:
const Counter = () => {
const [count, setCount] = useState(0)
const increment = () => {
setCount(count + 1);
}
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
</div>
)
}
default export Counter
As a small aside, I have heard a number of people discussing not using functional components for the performance reasons, specifically that
"Event handling functions are redefined per render in functional components"
Whilst true, please consider if your components are really rendering at such a speed or volume that this would be worth concern.
If they are, you can prevent redefining functions using useCallback
and useMemo
hooks. However, bear in mind that this may make your code (microscopically) worse in performance.
But honestly, I have never heard of redefining functions being a bottleneck in React apps. Premature optimisations are the root of all evil - worry about this when it's a problem.
Old Answer: You have the right idea. Go with functional if your component doesn't do much more than take in some props and render. You can think of these as pure functions because they will always render and behave the same, given the same props. Also, they don't care about lifecycle methods or have their own internal state.
Because they're lightweight, writing these simple components as functional components is pretty standard.
If your components need more functionality, like keeping state, use classes instead.
More info: https://facebook.github.io/react/docs/reusable-components.html#es6-classes
Solution 2
UPDATE March 2019
Building on what was stated in my original answer:
Are there any fundamental differences between React functions and classes at all? Of course, there are — in the mental model.
https://overreacted.io/how-are-function-components-different-from-classes/
UPDATE Feb 2019:
With the introduction of React hooks, it seems as though the React teams wants us to use functional components whenever possible (which better follows JavaScript's functional nature).
Their motivation:
1.) It’s hard to reuse stateful logic between components
2.) Complex components become hard to understand
3.) Classes confuse both people and machines
A functional component with hooks can do almost everything a class component can do, without any of the draw backs mentions above.
I recommend using them as soon as you are able.
Original Answer
Functional components aren't any more lightweight than class based components, "they perform exactly as classes." - https://github.com/facebook/react/issues/5677#issuecomment-241190513
The above link is a little dated, but React 16.7.0's documentation says that functional and class components:
are equivalent from React’s point of view
https://reactjs.org/docs/components-and-props.html#stateless-functions
There is essentially no difference between a functional component and a class component that just implements the render method, other than the syntax.
In the future (quoting the above link):
we [React] might add such optimizations
If you're trying to boost performance by eliminating unnecessary renders, both approaches provide support. memo
for functional components and PureComponent
for classes.
-https://reactjs.org/docs/react-api.html#reactmemo
-https://reactjs.org/docs/react-api.html#reactpurecomponent
It's really up to you. If you want less boilerplate, go functional. If you love functional programming and don't like classes, go functional. If you want consistency between all components in your codebase, go with classes. If you're tired of refactoring from functional to class based components when you need something like state
, go with classes.
Solution 3
Always try to use stateless functions (functional components) whenever possible. There are scenarios where you'll need to use a regular React class:
- The component needs to maintain state
- The component is re-rendering too much and you need to control that via
shouldComponentUpdate
- You need a container component
UPDATE
There's now a React class called PureComponent
that you can extend (instead of Component
) which implements its own shouldComponentUpdate
that takes care of shallow props comparison for you. Read more
Solution 4
As of React 17 the term Stateless Functional components is misleading and should be avoided (React.SFC deprecated, Dan Abramov on React.SFC), they can have a state, they can have hooks (that act as the lifecycle methods) as well, they more or less overlap with class components
Class based components
- state
- lifecycle methods
- memoization with React.PureComponent
Functional components:
- state (useState, useReducer hooks)
- lifecycle methods (via the useEffect, useLayoutEffect hooks)
- memoization via the memo HOC
Why i prefer Funtional components
- React provide the useEffect hook which is a very clear and concise way to combine the
componentDidMount
,componentDidUpdate
andcomponentWillUnmount
lifecycle methods - With hooks you can extract logic that can be easily shared across components and testable
- less confusion about the scoping
React motivation on why using hooks (i.e. functional components).
omarjmh
Updated on July 08, 2022Comments
-
omarjmh almost 2 years
After spending some time learning React I understand the difference between the two main paradigms of creating components.
My question is when should I use which one and why? What are the benefits/tradeoffs of one over the other?
ES6 classes:
import React, { Component } from 'react'; export class MyComponent extends Component { render() { return ( <div></div> ); } }
Functional:
const MyComponent = (props) => { return ( <div></div> ); }
I’m thinking functional whenever there is no state to be manipulated by that component, but is that it?
I’m guessing if I use any life cycle methods, it might be best to go with a class based component.
-
Rotareti almost 8 years
Always try to use stateless functions (functional components) whenever possible.
I have read ten people say that. Still none of them gave an explanation why. -
Diogo Cardoso almost 8 years
In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.
More info: facebook.github.io/react/docs/… -
door_number_three about 7 years@rotareti I don't know if you feel you got your question answered, but pure functions are much simpler to understand, test and maintain. Given the same parameters, they always render the same thing. Components that maintain state and change when lifecycle events occur are harder to understand. Not to say they aren't sometimes needed, but I hope it's clear that if their advantages are not needed, all they do is add unwanted boilerplate and overhead with no benefits.
-
Dobes Vandermeer almost 7 yearsYou will also want to create a Component class if you have your own event handler definitions. That way you can pre-bind those event handlers to the component in the constructor instead of creating a fresh new function on every render. Note this is not needed if all your event handlers come from props.
-
Dennis over 6 yearsWhat about functionality that isn't keeping state, but is tightly coupled to the component, e.g. determine some dynamic attribute for the render.
-
Arian Acosta over 6 yearsThis is the best article about the difference between the two types of components in React: code.tutsplus.com/tutorials/…
-
jeffski13 about 6 yearsI think making every component extend React.Component makes the code more readable, especially for the new people. It is nice when you see a component created the same way every time. Like @Galupuf said, simple components just have one method called "render()". It is also nice to make everything extend React.Component because when you want to start binding "this", having state, etc. you don't have to refactor everything, you can just add what you need.
-
Greg over 5 yearsAs of React 16.8, you can use state in a functional component, via the
useState
hook. -
polkovnikov.ph over 4 yearsAs of React 16.8, you can do almost everything in functional components, and all the effects can finally be modularized with only a minimal impact on performance.
-
johannchopin over 4 yearsWhere have you find the info where
Facebook officially recommends using functional components wherever possible
? -
n00b about 4 yearsI'm also curious about the
Facebook officially recommends using functional components wherever possible
. -
Garrett about 4 years
-
Garrett about 4 yearsNote that the quoted Facebook recommendation is no longer existent (see my comment above).
-
General Grievance almost 4 yearsWhat do you mean by, "Classes can't be reused?"
-
Danilo Souza Morães about 3 yearspoints 2 and 3 are as redundant as they are unfounded.
-
Danilo Souza Morães about 3 yearsclasses are one big component that cant be broken down or reused? What if you break a component into multiple class components?
-
EresDev almost 3 yearsWe break down classes all the time. All design patterns are about breaking down classes.
-
CodeConnoisseur over 2 years@jeffski13 so you are in favor of Class based react components? Or functional components?
-
coder9833idls over 2 yearsFair enough, making smaller classes in a sense is the same thing. You can have a small class component and nest it in different places. I meant a parent class component can't be re-used if you wanted to only render one element in it in different places. You can call an element inside a functional component in different places and not render the entire component- they are simply a function. You can call an element inside a function in a library without calling the entire function. If it is a class component, you can't do something like import fooFn.barElement, you have to call the entire class.
-
OzzyTheGiant over 2 years@rotareti, I can see the benefit of functional components (memoization), but from my personal encounters and experiences, I think functional components are much HARDER to reason about. I think people think all functional components will be written with just a few lines of code but many times I have found MASSIVE functional components doing way too many things at once; functions and event handlers everywhere; code is unreadable! Such code should be written in an object oriented way: either the component needs to be class-based or all those handlers need to be written as a class service.
-
Joe C. about 2 yearsIn your "new answer", could you answer when to use function vs class? Or are you saying that with hooks, functions are always preferred over class?