React gives us two ways of writing our components — functional components, and class components. In this blog, we will take a deep dive into the differences between the two, and the pros and cons of each.
First, what is a React Component?
React components are a way of defining a piece of UI into a reusable piece of code. A component is like a function, accepting inputs (called
props) and returning a React element, which describes what should be rendered to the DOM.
The Syntax Differences
Let’s take a look at the syntax of functional and class components — how to write each style of component, the different ways of using React state, and how to write lifecycle methods.
Example of Functional and Class Components
Now, here’s the equivalent component as a class component. This is simply an ES6 class that has a
render method which returns the JSX to be rendered.
state refers to an object inside a component that is used to store property values that belong to that component. When this
state object changes, the component re-renders.
State in Functional Components:
In a functional component, we can use the
useState hook to initialize state. If you are unfamiliar with React Hooks, I recommend taking a look at the docs here. React 16.8.0 is the first release version to support Hooks.
In the below example, we have added state to our
Profile example, where the state stores a single
useState accepts the initial value of the state property, and returns:
bio— the current state
setBio— a setter function that updates the state
State in Class Components:
In a class component, the
state object is initialized in the
constructor, and can be used anywhere in the component using
this.state.propertyName. In the below example, once again we have added state with
bio to our
Profile functional component example. We render this in the
render method using
Now let’s take a look at how to define lifecycle methods in each type of component. If you are unfamiliar with lifecycle components, check out the official documentation on State and Lifecycle.
Lifecycle methods in Class Components:
You may be familiar with
componentWillUnmount in React. As the names of these methods suggest:
componentDidMountis called once when the component is mounted, after the first
componentDidUpdateis invoked immediately after the component updates on re-renders. It is not called for the initial render
componentWillUnmountis invoked immediately before a component is unmounted and destroyed
In the below example, you can see how we can simply add these methods to a class component:
Lifecycle methods in Functional Components:
In functional components, we cannot simply add
React.useEffect hook allows us to achieve the same effect as these lifecycle methods:
React.useEffecthook accepts a callback, and an array of dependencies. The callback will only re-run if one of these dependencies change, so using
React.useEffectwith the second argument of
will only run once, and behaves the same as
- You can use
React.useEffectwith no dependencies provided, which will run on every re-render. This behaves the same as
componentDidUpdate, however will run after every render including the first render.
- You can return a function from
React.useEffectwhich will run when unmounting. This behaves the same as
You can see these implemented in the below example:
We’ve taken a look at both functional and class components, and seen the differences between them. Both have their pros and cons, however functional components have been increasingly popular for a few reasons:
- In the past, functional components were limited as you couldn’t use lifecycle methods or state. Since the introduction of hooks, you can achieve anything using a functional component that you can with a class component.
- The React team has mentioned that there may be future performance optimizations for functional components.
- Functional components are often cleaner and more concise, which leads to more readable and testable code.
All this being said, the React Team has no plans to remove class components from React. Both styles are valid and you can use whichever you prefer!
Hope this helped!