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>;
};
In class components:
import React, { Component } from "react";
class ClassComponent extends Component {
render() {
return <h1>Hello, world</h1>;
}
}
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" />
const FunctionalComponent = ({ name }) => {
return <h1>Hello, {name}</h1>;
};
we can write it without destructuring .
const FunctionalComponent = (props) => {
return <h1>Hello, {props.name}</h1>;
};
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>;
}
}
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>
);
};
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>
);
}
}
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>;
}
}
On Unmounting (componentWillUnmount):
class ClassComponent extends React.Component {
componentWillUnmount() {
console.log("Bye");
}
render() {
return <h1>Bye, World</h1>;
}
}
In functional components:
const FunctionalComponent = () => {
React.useEffect(() => {
console.log("Hello");//componentDidMount()
return () => {//componentWillUnmount()
console.log("Bye");
};
}, []);
return <h1>Hello, World</h1>;
};
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.
Top comments (0)