Type to generate custom UI components with AI

Type to generate UI components from text

OR

Browse thousands of MUI, Tailwind, React components that are fully customizable and responsive.

Explore Components

How to Convert Class Component to Functional Component

The web development landscape is an ever-evolving one, where processes are always optimized based on the programming language. Optimized processes usually involve new classes or functions, that simplify the processes older classes or functions take to accomplish a task, like how to convert class component to functional component.

React allows you to reuse bits of your code that form UI elements called components at different points in your project. The reusable bits could be for a button, navbar, card, and list components, this reusability allows for faster development.

By the end of this article, we will have explored React hooks, Class components, Functional components, and then how to convert class components to functional components.

How to Convert React Class Components to Hooks Based Function Component

If you are excited about learning this, then let’s get started 🚀

Overview of React Hooks

React Hooks are functions that allow you to use React state and other lifecycle methods in components. Though React hooks can only be used in functional components and not class components we will explore components more in the next section. Two common React hooks use useState and useEffect.

useState allows your functional components to have state variables, it allows you to track the state of a property or data in a functional component. useEffect allows you to perform side effects in your components, side effects could be timers, fetching data, or subscriptions.

Prerequisites

Though this article is simplified, it would be highly beneficial for you to have:

  • Familiarity with JavaScript

  • Familiarity with React

Before we proceed, here is a brief word about PureCode AI. PureCode is an AI-powered platform that’s built by developers for developers. It improves your workflow by allowing you to choose from over 10k AI-generated components.

Step 1 – Understanding a Class without State or Lifecycle Methods

Firstly let’s explore a React class with no state or lifecycle methods

Class Component Example

In the example below we have created a simple class component with no state or lifecycle methods.

import React, { Component } from 'react';

class App extends Component {
  // ... methods and render

  render() {
    return (
      <div>
        <h1>Hello, I am a Class Component!</h1>
      </div>
    );
  }
}

export default App;

Functional Equivalent

The code above shows a class component with no state or lifecycle methods, now let’s also look at its exact functional equivalent.

import React from 'react';

export default function App() {
 return (
      <div>
        <h1>Hello, I am a functional Component!</h1>
      </div>
    ); // ... functions and JSX
}

The components both carry out the same function and are therefore exactly the same thing, but a brief overview would show that the functional component has a simpler syntax than the class component.

Step 2 – Adding Hooks to Classes with State

Let’s explore adding hooks to classes with state, we have earlier explored that Hooks are functions that allow us to use States and lifecycle methods in components.

To handle State in React you have to set the state object with the variable and call the setState() function to update the variable.

For instance, if we have a global name variable we would need to update in the app, you have to define the name variable in the state object and update the name variable in the app by calling the setState() function.

Let’s now explore adding hooks in class and functional components.

If you want to get a quick grasp of How to Convert Class Based React Component to Hooks Based Functional Component, check out this video below:

Class Component with State Example

In the code, we added a state object with the name variable, the name variable is updated by calling the setState function by using the updateName method.

If you need to extend a component In Javascript, classes can extend other classes, thus inheriting the parent’s prototype. In fact, if you’re creating a class component, you have to extend the base component from React. This is more or less not possible with function components, so I wouldn’t bother trying Higher order components

import React, { Component } from 'react';

class App extends Component {
  state = {
    name: '',

  };

  handleChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  };

  render() {
    const { name } = this.state;
    return (
      <div>
        <input
          type="text"
          name="Name"
          value={name}
          onChange={this.handleChange}
          placeholder="name"
        />
      </div>
    );
  }
}

export default App;

Functional Equivalent with useState Hook

Now let’s add hooks to functional class components

import React, { useState } from 'react';

function App = () => {
  // Use the useState hook to declare the name variable and its updater function
  const [name, setName] = useState('');

  return (
    <div>
      <h1>Hello, {name}!</h1>
    </div>
  );
};
export default App;

In the functional component, we use the useState hook to declare the name variable and setName as the function to update the variable. this.state in a class component is equivalent to name in the functional component, likewise setName is equivalent to this.setState.

const [name, setName] = useState('Mike Joe')

A parameter determines the starting value of the state in The useState() hook is the initial value of the state. In this instance, we set it to Mike Joe.

This indicates that Mike Joe is the initial state of the name variable in the state. This example above shows how to convert a class component with a state to a functional component using Hooks.

Now let’s look at hooks with multiple state properties

Step 3 – Adding Hooks to Classes with Multiple State Properties

We just explored hooks in classes with just one state property, but while working on live projects most of your classes would most likely require or have classes with multiple state properties based on the required functionalities of the component.

The method above would mostly not work if you want to convert a class component with multiple state properties to a functional component. Let’s consider an instance where you have a form with input fields for userName, email, and phoneNumber, your component will have three state properties.

Class Component with Multiple State Properties Example

Class components with multiple state properties, the variables are still defined in the state object.

import React, { Component } from 'react';

class App extends Component {
  state = {
    userName: '',
    email: '',
    phoneNumber: ''
  };

  handleChange = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  };

  render() {
    const { userName, email, phoneNumber } = this.state;

    return (
      <div>
        <input
          type="text"
          name="userName"
          value={userName}
          onChange={this.handleChange}
          placeholder="Username"
        />
        <br />
        <input
          type="email"
          name="email"
          value={email}
          onChange={this.handleChange}
          placeholder="Email"
        />
        <br />
        <input
          type="tel"
          name="phoneNumber"
          value={phoneNumber}
          onChange={this.handleChange}
          placeholder="Phone Number"
        />
      </div>
    );
  }
}

export default App;
Class Component Multiple States

Functional Equivalent with Multiple useState Hook

To implement the multiple state properties in a functional component use the useState hook to call the variables.

import React, { useState } from 'react';

function App() {
  const [userName, setUsername] = useState('');
  const [email, setEmail] = useState('');
  const [phoneNumber, setPhoneNumber] = useState('');

  const handleChange = (e) => {
    const { name, value } = e.target;
    switch (name) {
      case 'userName':
        setUsername(value);
        break;
      case 'email':
        setEmail(value);
        break;
      case 'phoneNumber':
        setPhoneNumber(value);
        break;
      default:
        break;
    }
  };

  return (
    <div>
      <input
        type="text"
        name="userName"
        value={userName}
        onChange={handleChange}
        placeholder="Username"
      />
      <br />
      <input
        type="email"
        name="email"
        value={email}
        onChange={handleChange}
        placeholder="Email"
      />
      <br />
      <input
        type="tel"
        name="phoneNumber"
        value={phoneNumber}
        onChange={handleChange}
        placeholder="Phone Number"
      />
    </div>
  );
}

export default App;
Functional equivalent with Multiple Hook

In this functional equivalent, you observe that we call the useState hook for each state property, and the updater functions userName, email, and phoneNumber are used the update each of the variables. This example shows how you convert your multiple-state property class component to a functional component with useState.

Step 4 – Adding Hooks to a Class with State and componentDidMount

Now let’s explore a class with state and componentDidMount lifecycle method. The componentDidMount method is called when the component is rendered (mounted) on the screen and is usually used as a starting point for setting up subscriptions and fetching data.

Class Component with State and componentDidMount Example

Let’s consider a class component with a state and componentDidMount. Say the state is for three input fields that are to update to different values for a couple of seconds. The initial values of the states would have to be defined and then a componentDidMount to run after the input fields have been rendered to update the fields.

import React, { Component } from 'react';

class App extends Component {
  state = {
    userName: 'mikejoe',
    email: '[email protected]',
    phoneNumber: '123456789'
  }

  componentDidMount() {
    // ... update state after a delay
  }

  // ... methods and render
}

export default App;

When the app runs in the example above, the input field would initially have the values defined by the state object, and after the time interval specified, would be changed to the values defined in the componentDidMount method.

Functional Equivalent with useState and useEffect Hooks for componentDidMount

Let’s use the useStateand useEffect hooks to convert the class components to functional components

import React, { useState, useEffect } from 'react';

function App() {
  const [userName, setUsername] = useState('mikejoe');
  const [email, setEmail] = useState('[email protected]');
  const [phoneNumber, setPhoneNumber] = useState('123456789');

  useEffect(() => {
    // ... update state after a delay
  });

  // ... functions and JSX
}

export default App;

The useEffect hooks allow updating a state also after the component has been rendered. The hook allows you to carry outside effects tasks, it is called after every render.

The side effects tasks can include fetching data from API end-points, and setting up subscriptions or timers. This example explored how class components with the componentDidMount method can be converted to functional classes with the useEffect hook.

Step 5 – Adding Hooks to a Class with State, componentDidMount, and componentDidUpdate

We’ve explored adding hooks to class components with componentDidMount methods, though components might have multiple lifecycle methods.

Now let’s explore adding hooks to a class with State, componentDidMount, and componentDidUpdate methods. componentDidUpdate method updates a state after the component has been re-rendered with an updated value. The method is not called at the initial rendering of the component.

Class Component with State and Two Lifecycle Methods Example

In the example below, the component first renders the specified header text then after the specified time interval, updates the header state to the header text in the componentDidMount method.

The componentDidUpdate is called as the input field is filled and re-renders the component with the updated values.

import React, { Component } from 'react';

class App extends Component {
  state = {
    header: 'Welcome to Dev 2024'
  };

  componentDidMount() {
    // Update header after a delay
    setTimeout(() => {
      this.setState({ header: 'Delayed Welcome Message' });
    }, 2000); // Change 2000 to the desired delay in milliseconds
  }

  componentDidUpdate(prevProps, prevState) {
    // Update header when input changes
    if (prevState.inputValue !== this.state.inputValue) {
      this.setState({ header: 'Updated Welcome Message' });
    }
  }

  handleInputChange = (e) => {
    this.setState({ inputValue: e.target.value });
  };

  render() {
    return (
      <div>
        <h1>{this.state.header}</h1>
        <input
          type="text"
          value={this.state.inputValue || ''}
          onChange={this.handleInputChange}
          placeholder="Type something to update header"
        />
      </div>
    );
  }
}

export default App;
Class components with lifecycle method

Functional Equivalent with useState and useEffect Hooks for componentDidUpdate

import React, { useState, useEffect } from 'react';

const App = () => {
  const [header, setHeader] = useState('Welcome to Dev 2024');
  const [inputValue, setInputValue] = useState('');

  useEffect(() => {
    // Update header after a delay
    const delayTimeout = setTimeout(() => {
      setHeader('Delayed Welcome Message');
    }, 2000); // Change 2000 to the desired delay in milliseconds

    // Cleanup function for useEffect
    return () => clearTimeout(delayTimeout);
  }, []); // notice the empty dependency array

  useEffect(() => {
    // Update header when input changes
    if (inputValue) {
      setHeader('Updated Welcome Message');
    } else {
      setHeader('Welcome to Dev 2024');
    }
  }, [inputValue]);

  const handleInputChange = (e) => {
    setInputValue(e.target.value);
  };

  return (
    <div>
      <h1>{header}</h1>
      <input
        type="text"
        value={inputValue}
        onChange={handleInputChange}
        placeholder="Type something to update header"
      />
    </div>
  );
};

export default App;

In the above example, notice that instead of using the componentWillUnmount method to do cleanup before a component is removed from the React tree, return a function from the useEffect hook with an empty dependency array

Functional class with useEffect

The functional component syntax also allows you to optimize your code because you don’t have to write separate codes for the

componentDidMount()

and

componentDidUpdate()

methods. The

useEffect()

Hook provides the functionality of both because it runs components after the initial run and after every update.

Step 6 – Converting PureComponent to React memo

Now let’s explore converting React PureComponent to React Memo. PureComponent skips re-renders for both states and props but the same components work. If you need to skip re-rendering of a class component for states and props extend to PureComponent instead of component.

React.memo() allows you to skip the re-rendering of a component when props are unchanged. To create a memoized version of a component, wrap it in memo. As long as its props stay the same, this memoized version of your component won’t typically be re-rendered when its parent component does.

To understand why we use them, let’s look at the example below

import React, { Component } from 'react';

// Unstable component to monitor renders
function Unstable(props) {
  // Log how many times this component is rendered
  console.log('Rendered Unstable component');
  return (
    <div>
      <p>{props.value}</p>
    </div>
  );
}

class App extends Component {
  state = {
    counter: 1
  };

  componentDidMount() {
    // Increment the counter every two seconds
    this.intervalId = setInterval(() => {
      this.setState((prevState) => ({
        counter: prevState.counter + 1
      }));
    }, 2000);
  }

  render() {
    return (
      <div>
        <p>Counter Value: {this.state.counter}</p>
        <Unstable value="Unstable Component" />
      </div>
    );
  }
}

export default App;
Unstable

The unstable function is rendered because of the multiple re-rendering of the counter value in the counter component. This process can be optimized by using PureComponent or React.memo()

Class PureComponent Example

Re-rendering a component should usually only be necessary when its state or props have changed. To improve the example above, use PureComponent to have the component re-render only when the state or props change.

To accomplish this, import PureComponent and then extend it:

import React, { PureComponent } from 'react';

function Unstable(props) {
  console.log('Rendered Unstable component');
  return (
    <div>
      <p>{props.value}</p>
    </div>
  );
};
class App extends PureComponent {
// The class remains the same
}
export default App;

React is flexible but it has a single strict rule: All React components must act like pure functions with respect to their props.

PureComponent allows components to be re-rendered only when their state or props change, unlike the first example.

Functional Equivalent with React.memo

The same fix can be achieved using React.memo(). For us to achieve this fix we would have to wrap the component with React.memo(). The component only renders once and does not re-render again until there is a change in state or props.

import React, { Component }  from 'react';

const Unstable = React.memo(function Unstable (props) {
  console.log('Rendered Unstable component');
  return (
    <div>
      <p>{props.value}</p>
    </div>
  );
});
class App extends component {
// The class remains the same
}
export default App;
React.memo()

Check out this YouTube video on Converting from a Class Component to a Functional Component – React or React Native:

FAQs

How do you convert a React class component to a functional component?

Use Hooks like useState, useEffect, and useRef in your functional component to manage state, lifecycle methods, and references.

What are some key differences between class and functional components in React?

Class components use this.state and this.props, while functional components accept props as an argument and use Hooks like useState for state. Class components have lifecycle methods like componentDidMount, while functional components use useEffect.

Is it possible to migrate any class component to a functional component?

Yes, with Hooks you can replicate the capabilities of classes in functional components. Complex components may still be better suited for classes.

How do you pass data between class and functional components?

Pass data between components as props, regardless of whether they are classes or functions. You can also lift state and share via a context API.

How do you optimize the performance of functional components?

Wrap functional components in React.memo() to only re-render when props change, like PureComponent.

How do you reuse logic in functional components?

Extract reusable logic into custom Hooks that can be shared between components.

What is the functional equivalent of componentDidMount?

The useEffect Hook allows you to run code after initial render and on updates, like componentDidMount and componentDidUpdate.

How do you re-render a functional component?

Call the setter function returned from useState to update the state and trigger a re-render of your functional component.

Tabular Comparison of Class Components to Functional Components with Hooks

FeatureClass ComponentFunctional Component with Hooks
StateDefined in state object, updated with setState()Defined with useState Hook, updated by calling setter function
Lifecycle methodsDefined as class methods like componentDidMount()Use useEffect Hook which combines mounting and updating
Multiple state propertiesDefine each in state objectUse multiple useState Hooks
Performance optimizationExtend PureComponentWrap component in React.memo()
SyntaxClass-based with render() methodFunction-based, return JSX
Instance propertiesBound to thisUse ref or closures
Complex componentsBetter for classesHooks prefer simple functional components
Class featuresCan use class features like inheritanceFunctional only, no classes

What You Have Learned

In this article, we have explored React hooks, class components, functional components, and how to convert class components to functional components using React Hooks. We also explored the conversion of PureComponent to React.memo().

You now have the prerequisite React library knowledge to convert or work with functional components in your live projects.

In light of these advantages, visit Purecode AI to explore our library of UI components. Our library includes components that can be integrated into web applications built using Bootstrap, Tailwind CSS, and Material UI.

Get Started With PureCode AI

Emmanuel Uchenna

Emmanuel Uchenna

Emmanuel is an experienced and enthusiastic software developer and technical writer with 4+ proven years of professional experience. He focuses on full-stack web development. He is fluent in React, TypeScript, VueJS, and NodeJS and familiar with industry-standard technologies such as version control, headless CMS, and JAMstack. He is passionate about knowledge sharing.