How to Convert React Class Components to Functional Components

I have seen the library evolve from complex class structures to the elegant simplicity of functional components.

Moving away from classes isn’t just a trend; it significantly reduces boilerplate code and makes your logic much easier to test and share.

I remember spending hours debugging these binding issues in large enterprise dashboards before React Hooks were introduced in version 16.8.

Today, I want to show you exactly how to transform your legacy class components into modern functional ones using real-world scenarios.

Why Switch to Functional Components?

Functional components are essentially JavaScript functions that return JSX, making them more readable and less verbose than classes.

They eliminate the need for the this keyword, which is often a source of confusion for developers coming from other programming languages.

Method 1: Convert Basic State with the useState Hook

The most common task when converting a component is migrating the local state. In classes, we use this.state and this.setState.

In functional components, we use the useState hook. Let’s look at a simple Sales Tax Calculator used by retail businesses in Texas.

Class Component Version:

import React, { Component } from 'react';

class TaxCalculator extends Component {
  constructor(props) {
    super(props);
    this.state = {
      amount: 0,
      tax: 0
    };
  }

  calculateTax = (e) => {
    const val = e.target.value;
    this.setState({
      amount: val,
      tax: val * 0.0625 // Texas Sales Tax
    });
  }

  render() {
    return (
      <div style={{ padding: '20px' }}>
        <h2>Texas Sales Tax Calculator</h2>
        <input 
          type="number" 
          value={this.state.amount} 
          onChange={this.calculateTax} 
          placeholder="Enter USD Amount"
        />
        <p>Total Tax: ${this.state.tax.toFixed(2)}</p>
      </div>
    );
  }
}

export default TaxCalculator;

Functional Component Version:

import React, { useState } from 'react';

const TaxCalculator = () => {
  const [amount, setAmount] = useState(0);
  const [tax, setTax] = useState(0);

  const handleCalculation = (e) => {
    const val = e.target.value;
    setAmount(val);
    setTax(val * 0.0625);
  };

  return (
    <div style={{ padding: '20px' }}>
      <h2>Texas Sales Tax Calculator</h2>
      <input 
        type="number" 
        value={amount} 
        onChange={handleCalculation} 
        placeholder="Enter USD Amount"
      />
      <p>Total Tax: ${tax.toFixed(2)}</p>
    </div>
  );
};

export default TaxCalculator;

You can see the output in the screenshot below.

Convert React Class Components to Functional Components

As you can see, the functional approach is much cleaner and removes the need for a constructor.

Method 2: Replace Lifecycle Methods with useEffect

In the past, we relied heavily on componentDidMount, componentDidUpdate, and componentWillUnmount.

The useEffect hook now handles all these lifecycle events in a single, unified API.

Suppose we are building a weather widget that fetches current temperatures for New York City when the component loads.

Class Component Version:

import React, { Component } from 'react';

class NYCWeather extends Component {
  constructor(props) {
    super(props);
    this.state = { weather: 'Loading...', lastUpdated: '' };
  }

  componentDidMount() {
    this.timerID = setInterval(() => this.tick(), 1000);
    console.log("Fetching weather for NYC...");
    // Imagine an API call here
    this.setState({ weather: 'Sunny 75°F' });
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({ lastUpdated: new Date().toLocaleTimeString() });
  }

  render() {
    return (
      <div>
        <h3>New York City Weather</h3>
        <p>Condition: {this.state.weather}</p>
        <p>Last Sync: {this.state.lastUpdated}</p>
      </div>
    );
  }
}

export default NYCWeather;

Functional Component Version:

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

const NYCWeather = () => {
  const [weather, setWeather] = useState('Loading...');
  const [lastUpdated, setLastUpdated] = useState('');

  useEffect(() => {
    console.log("Fetching weather for NYC...");
    setWeather('Sunny 75°F');

    const timerID = setInterval(() => {
      setLastUpdated(new Date().toLocaleTimeString());
    }, 1000);

    // This return function acts as componentWillUnmount
    return () => clearInterval(timerID);
  }, []); // Empty array means it runs only once (componentDidMount)

  return (
    <div>
      <h3>New York City Weather</h3>
      <p>Condition: {weather}</p>
      <p>Last Sync: {lastUpdated}</p>
    </div>
  );
};

export default NYCWeather;

You can see the output in the screenshot below.

How to Convert React Class Components to Functional Components

Method 3: Handle Props and Destructuring

In class components, you access props via this.props. In functional components, props are passed as an argument to the function.

I always recommend destructuring props right in the function signature to keep the code tidy.

Here is an example of a “Contact Card” for a real estate agent in California.

Class Component Version:

import React, { Component } from 'react';

class AgentCard extends Component {
  render() {
    return (
      <div className="card">
        <h1>{this.props.name}</h1>
        <p>License: {this.props.licenseNo}</p>
        <p>Location: {this.props.city}, CA</p>
      </div>
    );
  }
}

Functional Component Version:

import React from 'react';

const AgentCard = ({ name, licenseNo, city }) => {
  return (
    <div className="card">
      <h1>{name}</h1>
      <p>License: {licenseNo}</p>
      <p>Location: {city}, CA</p>
    </div>
  );
};

Method 4: Convert Context Consumers

If your application uses the React Context API to manage global data like “User Themes” or “Subscription Levels,” the transition is even more dramatic.

The useContext hook allows you to grab context values without wrapping your JSX in a consumer component.

Let’s look at a Membership Status component for a US-based streaming service.

Class Component Version:

import React, { Component } from 'react';
import { UserContext } from './UserContext';

class MembershipStatus extends Component {
  render() {
    return (
      <UserContext.Consumer>
        {context => (
          <div>
            <p>Welcome, {context.userName}</p>
            <p>Your Plan: {context.planType}</p>
          </div>
        )}
      </UserContext.Consumer>
    );
  }
}

Functional Component Version:

import React, { useContext } from 'react';
import { UserContext } from './UserContext';

const MembershipStatus = () => {
  const context = useContext(UserContext);

  return (
    <div>
      <p>Welcome, {context.userName}</p>
      <p>Your Plan: {context.planType}</p>
    </div>
  );
};

Method 5: Use useReducer for Complex State

Sometimes, using useState multiple times can become messy when your state transitions are complex.

In classes, you might have handled this with a giant setState object. In functional components, useReducer is the preferred way.

Consider a Flight Booking form for a trip from LAX to JFK.

Class Component Version:

import React, { Component } from 'react';

class FlightBooking extends Component {
  state = {
    passengers: 1,
    class: 'Economy',
    insurance: false
  };

  updateField = (field, value) => {
    this.setState({ [field]: value });
  };

  render() {
    return (
      <div>
        <h2>LAX to JFK Booking</h2>
        <button onClick={() => this.updateField('passengers', this.state.passengers + 1)}>
          Add Passenger
        </button>
        <p>Current Passengers: {this.state.passengers}</p>
      </div>
    );
  }
}

Functional Component Version:

import React, { useReducer } from 'react';

const initialState = { passengers: 1, class: 'Economy', insurance: false };

function reducer(state, action) {
  switch (action.type) {
    case 'ADD_PASSENGER':
      return { ...state, passengers: state.passengers + 1 };
    case 'SET_CLASS':
      return { ...state, class: action.payload };
    default:
      return state;
  }
}

const FlightBooking = () => {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <h2>LAX to JFK Booking</h2>
      <button onClick={() => dispatch({ type: 'ADD_PASSENGER' })}>
        Add Passenger
      </button>
      <p>Current Passengers: {state.passengers}</p>
      <p>Travel Class: {state.class}</p>
    </div>
  );
};

You can see the output in the screenshot below.

Convert Class Components to Functional Components in React

Method 6: Reference DOM Elements with useRef

In class components, you create a ref using React.createRef(). In functional components, you use the useRef hook.

This helps focus an input field, like a Zip Code entry on a US Postal Service form.

Class Component Version:

import React, { Component } from 'react';

class ZipCodeForm extends Component {
  constructor(props) {
    super(props);
    this.zipInput = React.createRef();
  }

  focusInput = () => {
    this.zipInput.current.focus();
  }

  render() {
    return (
      <div>
        <input ref={this.zipInput} type="text" placeholder="Enter Zip Code" />
        <button onClick={this.focusInput}>Focus Field</button>
      </div>
    );
  }
}

Functional Component Version:

import React, { useRef } from 'react';

const ZipCodeForm = () => {
  const zipInput = useRef(null);

  const focusInput = () => {
    zipInput.current.focus();
  };

  return (
    <div>
      <input ref={zipInput} type="text" placeholder="Enter Zip Code" />
      <button onClick={focusInput}>Focus Field</button>
    </div>
  );
};

Converting your components from classes to functions is one of the best things you can do for your React project.

It makes the code more reusable, easier to read, and aligns your project with the future of the React ecosystem.

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.