Convert React Class Components to React Functional Components

React since version 16.7 has given us a way to create React components a new way. Instead of the traditional class syntax, we can now use a function to create a React component.

These two are both React components:

jsx
// a class component -------------------
import { Component } from 'react';

class App extends Component {
  render() {
    return <h1>Hello World</h1>;
  }
}

// a functional React component -------------------
function App() {
  return <h1>Hello World</h1>;
}

Functional React components make it easier to write reusable components. They are also more concise and easier to understand.

There are ways to convert React class components over to React functional components. We have to keep learn how to convert certain concepts from React class components to functional React components.

All React components need to have a way to keep state. This is the main concept in how React updates our views with new information. Whenever we update state, React will quickly update what our users see.

In class components, we will use this.state and this.setState() to manage state.

jsx
import { Component } from 'react';

class App extends Component {
  state = { activeUser: "Chris" };

  changeUser = () => {
    this.setState({ activeUser: "Bolingo!" });
  };

  render() {
    return (
      <div>
        <p>Active User is: {this.state.activeUser}</p>

        <button onClick={this.changeUser}>Change Me!</button>
      </div>
    );
  }
}

To convert this to a functional component, we need to use useState() instead of this.state.

Then we can use setActiveUser() instead of this.setState(). We can see that React functional components allow us to write less code.

jsx
import { useState } from 'react';

function App() {
  const [activeUser, setActiveUser] = useState("Chris");

  return (
    <div>
      <p>Active User is: {activeUser}</p>

      <button onClick={() => setActiveUser("Bolingo!")}>Change Me!</button>
    </div>
  );
}

If we have multiple state variables, we need to create a new useState() for each one.

Often, we will want to run some code after a component mounts. This is where componentDidMount() comes in. When we switch to functional components, we will use useEffect() instead of componentDidMount().

jsx
import { Component } from "react";

class App extends Component {
  state = {
    message: "What's happening this week?"
  };

  // update our message every time the component mounts after 5 seconds
  componentDidMount() {
    setTimeout(() => {
      this.setState({ message: "I only know it's gon be lit!!" });
    }, 5000);
  }

  render() {
    return (
      <div>Status: {this.state.message}</div>
    );
  }
}

We can now use a React effect that will run when our component mounts.

jsx
import { useState } from "react";

function App() {
  const [message, setMessage] = useState("What's happening this week?");

  useEffect(() => { 
    setTimeout(() => setMessage("I only know it's gon be lit!!"), 5000);
  }, []); // empty array here means that we only want to run this effect once

  return <div>Status: {message}</div>;
}

useEffect() takes two arguments. The second array is the dependencies. This is an array of variables that we want to watch for changes. If any of these variables change, we will run the effect again. To get an effect to run only when a React component mounts, we pass in an empty array as the second argument.

React's useState() and useEffect() are versatile tools that can accommodate many different use cases. Converting React class components to React functional components is a great way to write more concise code.

Want to improve your coding and design skills?

I'm continually researching the best practices and tools for coding.
Join 50,000+ developers looking to make cool stuff.

We value your privacy. 1-click unsubscribe.

Chris Sev

Chris Sev

Chris Sev is the co-founder of Better Dev. Coding better every day. Previously he created Scotch.io which was acquired.

Comments

What did you think of the article? Let us know!
(these comments are powered by GitHub issues and use 0 trackers)