391

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.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
omarjmh
  • 13,632
  • 6
  • 34
  • 42
  • 4
    If you have a component with render method only, you can turn it into functional form. If you need something more than stateless render function, use classes – just-boris Mar 20 '16 at 19:02
  • 2
    To be even more concise try this: `const MyComponent = (props) =>
    ...
    `
    – Viliam Simko Aug 15 '17 at 10:57
  • 2
    I never use functional if it can be avoided. Because I inevitably end up needing to refactor to class-based down the road. And then often need to refactor back to functional after that. – keithjgrant Apr 27 '18 at 16:19
  • 7
    In 2020 the correct approach is to use functional components wherever possible, because they support hooks, and hooks are (performance-wise and architecturally) better than alternatives. – polkovnikov.ph Jan 04 '20 at 07:30
  • @polkovnikov.ph where did you get your conclusion from? I agree with you but what are you basing you conclusion off of? Thank you. – CodeConnoisseur Feb 18 '20 at 19:58
  • Mostly from personal experience using those in production, where I've seen 1.2x improvement in render time after ad hoc rewriting to hooks, and 10x improvement in places where classes previously enforced usage of underpar programming techniques. Also HOCs are impossible to type in TypeScript, make tracing data paths through props significantly harder, and are very slow. So with class components it was impossible to keep code DRY and have good product at the same time. – polkovnikov.ph Feb 19 '20 at 00:10
  • IMHO, React job is knowing when to rerender bits of UI, and rerender when necessary. To make this decision, React needs to know if component state has changed and if this change should trigger a rerender. Check for changes in complex objects is a difficult task. Using immutable objects makes it easier (just an address change check) for React. Immutability is part of functional programming. So, from what I understand, functional components makes it easier for React folks to make React good at what it has to do : render a UI when necessary. UI is a function of state after all. – Florian Motteau Mar 10 '20 at 17:56
  • 1
    @polkovnikov.ph do you still feel that using functional components is better than class based components? – CodeConnoisseur Jan 01 '22 at 16:02
  • 1
    @PA-GW It never was anything subjective. Class-based API was not removed from React because you might still want to use old libraries. Otherwise it's extinct in production code pretty much everywhere for years. – polkovnikov.ph Jan 01 '22 at 21:30
  • @polkovnikov.ph good to know...so I should always be using functional components. Sorry if I ask newb questions...but how do functional react components handle using state etc...? – CodeConnoisseur Jan 02 '22 at 16:15
  • @PA-GW It's thoroughly described in [documentation](https://reactjs.org/docs/hooks-intro.html). – polkovnikov.ph Jan 03 '22 at 00:59

8 Answers8

303

New Answer: Much of the below was true, until the introduction of React Hooks.

  • componentDidUpdate can be replicated with useEffect(fn), where fn is the function to run upon rerendering.

  • componentDidMount methods can be replicated with useEffect(fn, []), where fn 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 with useState(), 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

Liam
  • 27,717
  • 28
  • 128
  • 190
Jeff Cousins
  • 3,381
  • 1
  • 9
  • 6
  • What about functionality that isn't keeping state, but is tightly coupled to the component, e.g. determine some dynamic attribute for the render. – Dennis Oct 23 '17 at 19:47
  • This is the best article about the difference between the two types of components in React: https://code.tutsplus.com/tutorials/stateful-vs-stateless-functional-components-in-react--cms-29541 – Arian Acosta Feb 07 '18 at 20:54
  • 8
    As of React 16.8, you can use state in a functional component, via the `useState` hook. – Greg Mar 27 '19 at 18:30
  • As 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. – polkovnikov.ph Jan 04 '20 at 07:33
  • 5
    Where have you find the info where `Facebook officially recommends using functional components wherever possible`? – johannchopin Mar 27 '20 at 07:56
  • 1
    I'm also curious about the `Facebook officially recommends using functional components wherever possible`. – n00b Apr 16 '20 at 23:30
  • 12
    Seems FB's recommendation has changed over time: In [2016-June](https://web.archive.org/web/20160608001717/http://facebook.github.io/react/docs/reusable-components.html), they recommended functional components, in [2016-Oct](https://web.archive.org/web/20161019074256/https://facebook.github.io/react/docs/reusable-components.html) they recommended functional components when you don't need state, ES6 classes when you do and in [2016-Nov](https://web.archive.org/web/20161103110003/https://facebook.github.io/react/docs/components-and-props.html), their recommendation was removed altogether. – Garrett Jun 25 '20 at 15:31
  • In 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? – Joe C. Apr 03 '22 at 22:49
76

UPDATE Jan 2023

TLDR; Functions are the best way to create components. React.Component is a legacy API.

"We recommend defining components as functions instead of classes."

"Class components are still supported by React, but we don’t recommend using them in new code."

https://react.dev/reference/react/Component

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 (April 2018)

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.

Galupuf
  • 2,827
  • 1
  • 12
  • 29
  • 2
    I 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. – jeffski13 Apr 02 '18 at 15:02
  • 1
    points 2 and 3 are as redundant as they are unfounded. – Danilo Souza Morães Jun 12 '21 at 01:46
  • @jeffski13 so you are in favor of Class based react components? Or functional components? – CodeConnoisseur Jan 04 '22 at 13:02
  • Maybe there is something I am missing. However it seems like if your problem at hand would benefit from a class structure then it might be a good idea to go with a class. For example if you think inheritance would be nice to have, then go with a class. If you want to be able to unit test the separate functions of a class then go with a class. I feel like most of the time it makes sense to go functional but sometimes having a class can be preferable. – slipperypete Jan 25 '23 at 00:51
46

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

ffxsam
  • 26,428
  • 32
  • 94
  • 144
  • 74
    `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. – Rotareti Jul 12 '16 at 18:15
  • 33
    `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: https://facebook.github.io/react/docs/reusable-components.html#stateless-functions – Diogo Cardoso Aug 18 '16 at 12:56
  • 4
    @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. – door_number_three May 18 '17 at 17:59
  • You 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. – Dobes Vandermeer Aug 21 '17 at 18:51
  • Note that the quoted Facebook recommendation is no longer existent (see [my comment](https://stackoverflow.com/questions/36097965/when-to-use-es6-class-based-react-components-vs-functional-es6-react-components#comment110667347_36137801) above). – Garrett Jun 25 '20 at 15:32
  • @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. – OzzyTheGiant Jan 30 '22 at 15:39
  • @door_number_three Ok a simple function component is stateless, but as soon as you start using `useState` your fonction is no longer stateless! And saying `Given the same parameters, they always render the same thing.` is just wrong! I really feel like this whole function component got started by functionnal hype, then a bunch of stateful hooks got added, and now we just end up with huge impure functions using a ton of hooks that are really hard to refacto – Alexandre Daubricourt Dec 03 '22 at 14:36
  • When having this conversation. I hear all the time. "Try to write functional components". I never hear anybody say use a class component if you think your problem would benefit from features that classes offer such as inheritance, a constructor, the ability to test specific functions without essentially testing the entire render method. I feel like functional components can be used most of the time. But sometimes a class makes sense. – slipperypete Jan 25 '23 at 00:59
31

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

Functional components:

Why i prefer Funtional components

  • React provide the useEffect hook which is a very clear and concise way to combine the componentDidMount, componentDidUpdate and componentWillUnmount 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).

Karim
  • 8,454
  • 3
  • 25
  • 33
2

I have used functional components for heavily used application which is in production. There is only one time I used class components for "Error Boundaries" because there is no alternative "Error Boundaries" in functional components.

I used "class component" literally only one time.

0

Class-based components offer a more structured and organized way to define and implement a component, and they provide additional features and capabilities, such as the ability to use local state and lifecycle methods. This can make them a good choice for creating complex components that require a lot of logic and functionality.

On the other hand, functional components are simpler and easier to work with, and they can be more performant because they are more lightweight. They are also easier to test and debug, because they are pure functions that don't have side effects. This makes them a good choice for creating simple components that don't require a lot of logic or state management.

cya
  • 118
  • 2
  • 9
0

Despite Having so many useful features in function components, There are some cases in which we need to use the Class component over the Function component:

1. Error boundary

When an error occurs usually it displays a component tree that crashed on screen, it can leave a bad impression on the end-user.

Error boundaries help us deal with this situation. Error boundaries allow us to display fallback UI when an error occurs inside a component.

We can use error boundaries to trace client-side errors and provide useful information for debugging. It's not possible to create an error boundary with a function component.

Error boundaries can only be implemented with class components.

2. Pure Component

Many times, we need to avoid unnecessary re-rendering of components depending on certain criteria.

In such cases, We can use pure components by extending React.PureComponent, as they have a static method "shouldComponentUpdate" that decides whether to re-render or not based on the component's props and state.

Many times react js developers use the "useMemo" hook to avoid unnecessary re-rendering like this :

   const App=()=>{

                return useMemo(()=>{
                    return <>{/*Code*/}</>
                  },[dependancies])
              }

However, everything before the "useMemo" hook will still be executed when the component updates its state. Therefore, "useMemo" may not always be the best option for avoiding unnecessary re-rendering.

Since we cannot create pure components with function components, we will need to use class components.

3. Life Cycle methods

I know This should not be the case, because most lifecycle methods like componentDidMount, componentDidUpdate, or componentWillUnmount can be replaced with useEffect.

It is important to note that the useEffect hook requires some extra care when it comes to dependencies and avoiding infinite loops.

One has to be very careful about dependency. and make sure dependency is not updated from inside the hook (this can lead to an infinite loop)

In a class component, the lifecycle methods are executed automatically when certain events occur, such as when the component is mounted, updated, or unmounted.

Jatin Parmar
  • 2,759
  • 5
  • 20
  • 31
-1

Forms are easier with functional, because you can reuse form input fields and you can break them apart with React display conditionals.

Classes are one big component that can't be broken down or reused. They are better for function-heavy components, like a component that performs an algorithm in a pop-up module or something.

Best practice is reusability with functional components and then use small functional components to assemble complete sections, ex.- form input fields imported into a file for a React form.

Another best practice is to not nest components in the process of doing this.

  • 4
    What do you mean by, "Classes can't be reused?" – General Grievance Sep 08 '20 at 11:59
  • 1
    classes are one big component that cant be broken down or reused? What if you break a component into multiple class components? – Danilo Souza Morães Jun 12 '21 at 01:48
  • 1
    We break down classes all the time. All design patterns are about breaking down classes. – Eres Jul 16 '21 at 20:37
  • Fair 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. – coder9833idls Jan 12 '22 at 05:06