Convert a React Class Component into a Functional Component.
In ReactJS, class components are the traditional way of building components but with the release of ReactJS 16.8, functional components were introduced and it made writing components much more simpler, cleaner and faster than class components 🙌🏻
Many companies and developers initially started with class components in their React applications but now find it difficult to migrate to Functional components.
This is where our article will help you to convert the legacy class-based components into more efficient functional components. The future developers will definitely thank you for this. So go ahead and be a hero! 😎
Difference between class and functional components
Before we proceed, it's important to understand the key differences between class and functional components. To learn about it, you can read this article.
Steps to convert a React class component to a functional component
let's consider the following react class component example:
import React, { Component } from "react"; class Counter extends Component { constructor(props) { super(props); this.state = { count: 0, }; } componentDidMount() { // asyncronous calls/ data fetching console.log("Component did mount"); } componentDidUpdate(prevProps, prevState) { if (prevState.count !== state.count) { console.log("Count changed"); } console.log("Component did update"); } componentWillUnmount() { console.log("Component will unmount"); } handleClick() { this.setState((prevState) => ({ count: prevState.count + 1, })); } render() { const multiplicationValue = count * 2; return ( <div> <p>count multiplied by 2 is equal to {multiplicationValue} </p> <p>You clicked {this.state.count} times</p> <button onClick={this.handleClick}>Click me</button> </div> ); } } export default Counter;
-
Paste all the imports at the top
The first step is to place all the import on top of your file.
import React from "react";
-
Convert the class into an arrow function
An arrow function takes props as an argument, which is an object that contains the properties passed from the parent component. You can also destructure the props.
from this
class Counter extends Component { //... }
to this
const Counter = (props) => { //... };
-
Define the State and Props using react hooks
The second step is to identify the state and props used in the class component and redefine using react useState hook.
from this
class Counter extends Component { constructor(props) { super(props); this.state = { count: 0, }; } }
to this
import React, { useState } from "react"; const Counter = (props) => { const [count, setCount] = useState(0); };
-
Remove react render method
The render() method is responsible for rendering the component's HTML. In a class component, the render() method is mandatory. However, in a functional component, you can use the return statement to directly return the JSX. If you have any code before the return statement in a class component, just let it stay there.
from this
// ... render() { const multiplicationValue = count*2; return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={this.handleClick}>Click me</button> </div> ); } // ...
to this
const multiplicationValue = count * 2; return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={this.handleClick}>Click me</button> </div> );
-
Rewrite all functions into arrow functions and remove event handler bindings
In a functional component, we can write arrow functions instead of having functions defined with traditional function syntax.
Also, we no longer need to bind event handlers with function components in the constructor. So, go ahead and remove them.
from this
// ... handleClick() { this.setState(prevState => ({ count: prevState.count + 1 })); } // ...
to this
const handleClick = () => { setCount(count + 1); }
-
Replace the Lifecycle Methods using useEffect hook
To define various react lifecycle methods we need to use the useEffect hook as shown below
from this
componentDidMount() { // asyncronous calls/ data fetching console.log('Component did mount'); } componentDidUpdate(prevProps, prevState) { if(prevState.count !== state.count ) { console.log('Count changed'); } console.log('Component did update'); } componentWillUnmount() { console.log('Component will unmount'); }
to this
// handle any state side effects by passing dependency to useEffect useEffect(() => { console.log("Count changed"); }, [count]); // componentDidMount useEffect(() => { // asyncronous calls/ data fetching console.log("Component did mount"); // componentWillUnmount- return a function you to execute on unmount return () => { console.log("component will unmount"); }; }, []); // componentDidUpdate useEffect(() => { console.log("Component did update"); });
-
Conclusion
With the steps outlined in this article, you can quickly and easily convert your class components to functional components. One of the main benefits of using functional components is that they are easier to read and write. They are also easier to test and debug, which can save you a lot of time in the long run.