DEV Community

loading...
Cover image for Migrating From Class To Functional Components With Hooks

Migrating From Class To Functional Components With Hooks

punya2004
If you love React, you’ll feel right at home here.
・3 min read

What’s the difference,which should you use in your app,and why?

Since React is so popular among developers today, this blog is
intended to give you the pros and cons of React hooks vs. classes
through React useState() and useEffect()’s hooks API.

Rendering JSX:

First of all, the clear difference is the syntax. Just like in
their names, a functional component is just a plain JavaScript function that returns JSX. A class component is a JavaScript class that extends React.Component which has a render method.

Let’s take a look into a simple example.

In functional components:

import React from "react";

const FunctionalComponent = () => 
{
    return <h1>Hello, world</h1>;
};
Enter fullscreen mode Exit fullscreen mode

In class components:

import React, { Component } from "react";

class ClassComponent extends Component {
 render() {
   return <h1>Hello, world</h1>;
 }
}
Enter fullscreen mode Exit fullscreen mode

Passing props:

Inside a functional component, we are passing props as an argument of the function. Note that we are using destructuring here.

In functional components:

<Component name="punya" />
Enter fullscreen mode Exit fullscreen mode
const FunctionalComponent = ({ name }) => {
 return <h1>Hello, {name}</h1>;
};

Enter fullscreen mode Exit fullscreen mode

we can write it without destructuring .

const FunctionalComponent = (props) => {
 return <h1>Hello, {props.name}</h1>;
};
Enter fullscreen mode Exit fullscreen mode

In class components:

Since it is a class, you need to use this to refer to props.

class ClassComponent extends React.Component {
  render() {
    const { name } = this.props;
    return <h1>Hello, { name }</h1>;
 }
}
Enter fullscreen mode Exit fullscreen mode

Handling state:

Handling state was only doable in a class component until
recently, React Hook useState was introduced to allow developers to write stateful functional components.

Handling state in functional components:

const FunctionalComponent = () => {
 const [count, setCount] = React.useState(0);

 return (
   <div>
     <p>count: {count}</p>
     <button onClick={() => setCount(count + 1)}>Click</button>
   </div>
 );
};
Enter fullscreen mode Exit fullscreen mode

To use state variables in a functional component, we need to use
useState Hook, which takes an argument of initial state and
returns the current state and a function that updates it.

Handling state in class components:


class ClassComponent extends React.Component {
 constructor(props) {
   super(props);
   this.state = {
     count: 0
   };
 }

 render() {
   return (
     <div>
       <p>count: {this.state.count} times</p>
       <button onClick={() => this.setState({ count: this.state.count + 1 })}>
         Click
       </button>
     </div>
   );
 }
}
Enter fullscreen mode Exit fullscreen mode

The idea is still the same but a class component handles state a
bit differently. Basically, without implementing the constructor and calling super(props), all the state variables that you are
trying to use will be undefined. So let’s define the constructor first.
Inside the constructor, you will make a state object with a state
key and initial value. And inside JSX, we use this.state.count to access the value of the state .

Lifecycle Methods:

As you already know, lifecycles play an important role in the
timing of rendering.

In class components:

On Mounting (componentDidMount):

class ClassComponent extends React.Component {
 componentDidMount() {
   console.log("Hello");
 }

 render() {
   return <h1>Hello, World</h1>;
 }
}
Enter fullscreen mode Exit fullscreen mode

On Unmounting (componentWillUnmount):

class ClassComponent extends React.Component {
 componentWillUnmount() {
   console.log("Bye");
 }

 render() {
   return <h1>Bye, World</h1>;
 }
}
Enter fullscreen mode Exit fullscreen mode

In functional components:

const FunctionalComponent = () => {
 React.useEffect(() => {
   console.log("Hello");//componentDidMount()
      return () => {//componentWillUnmount()
     console.log("Bye");
   };
 }, []);
 return <h1>Hello, World</h1>;
};
Enter fullscreen mode Exit fullscreen mode

Replacing componentDidMount, We use the useEffect hook with the second argument of []. The second argument of the useState hook is normally an array of a state(s) that changes, and useEffect will be only called on these selected changes. But when it’s an empty array like this example, it will be called once on mounting. This is a perfect replacement for a componentDidMount. componentDidMount is a lifecycle method that is called once after the first render.

unmounting inside the useEffect function. This is especially
useful when you have to clean up the subscriptions such as a
clearInterval function, otherwise it can cause a severe memory
leak on a bigger project. One advantage of using useEffect is
that we can write functions for both mounting and unmounting in
the same place.

Conclusion:

I would like to conclude that functional components are taking
over modern React in the foreseeable future. As we noticed in the examples, a functional component is written shorter and simpler, which makes it easier to develop, understand, and test. Class
components can also be confusing with so many uses of this. Using functional components can easily avoid this kind of mess and keep everything clean.

Discussion (0)