React Hooks vs Class Components
Moazam Ali
Posted on September 22, 2022
In today’s world React is the most popular frontend library used by frontend developers. The main reason it is most preferred is because of its simplicity to reuse code, speed, virtual DOM, and components.
Originally, React mainly used class components but classes are hard to understand. The structure of class components is not that much difficult but it may become complicated when life cycle methods come into existence.
So to understand the comparison of Hooks and Classes we would first understand what is a state in React and how it is being managed by Classes and Hooks.
What is a state in React?
The state
object is where you store property value pairs that belong to the component. It is a built-in React object that contains data or information about the components and whenever this object changes, the component is re-rendered.
One thing that becomes the point of confusion for many is the difference between state and props. The state _is mutable, it is defined and managed inside of the component. While _Props are the properties that are passed into the fellow components where they can be used, it is read-only which means props
are immutable.
Managing state in Class Components
Before React 16.8, Class components were the only way to track the state and lifecycle of a React component because function components were considered state-less. After the introduction of React hooks, Function components are almost equivalent to Class components.
Simple class component:
import React from ‘react’;
class Counter extends React.Component {
render() {
return (
<div>
Hello, React!
</div>
)
}
}
export default Counter;
To access and manage the state object in the class component we need to initialize this.state
as an object inside of the constructor()
.
class CounterApp extends React.Component {
constructor() {
super();
this.state = {
counter: 0,
};
}
render() {
return <div> { /* code */ } </div>;
}
}
So here we have created a Counter
class in which we have created a constructor function. Whenever the component gets initiated, the constructor is called. We have created a state
object having a property of counter initialized with 0
. super()
is used to call the constructor of its parent class.
Let us implement a simple counter application to understand the working of Classes in React:
import React from "react";
class CounterApp extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
};
}
render() {
return (
<div>
<h2>Count: {this.state.counter}</h2>
<button onClick={() => this.setState({ counter: this.state.counter + 1 })} >
Increment
</button>
<button onClick={() => this.setState({ counter: this.state.counter - 1 })} >
Decrement
</button>
</div>
);
}
}
export default CounterApp;
The onClick
function would get a callback function which would call the setState()
method and would update the value of the counter. setState()
will ensure that the component knows it's been updated and calls the render
method.
Managing state in React Hooks?
Before React 16.8 functional components were state-less, so to use states and lifecycles inside of functional components, Hooks were introduced. React hooks are used inside functional components.
Simple Functional Component:
import React from ‘react’;
function Counter() {
return (
<div>
Hello, React!
</div>
)
}
export default Counter;
useState()
is a hook that allows us to play with the state in functional components in react. It helps us to pass in-state variables in a functional component. It returns an array with two elements: the first one is the state variable and the second one is the function that updates the variable.
Taking the same Counter Component but this time we would write it in a functional component.
function CounterApp() {
const [counter, setCounter] = useState(0);
return (
<div>
{ /* code */ }
</div>
);
}
Now we have defined our state in a functional component.
const [counter, setCounter] = useState(0);
in this line we are doing array destructuring to get the values from useState
and storing it in the variables.
Now let’s implement the same counter application but this time we would use hooks.
import React from "react";
function CounterApp() {
const [counter, setCounter] = useState(0);
return (
<div>
<h2>Count: {counter}</h2>
<button
onClick={() => setCounter(counter + 1)} >
Increment
</button>
<button
onClick={() => setCounter(counter - 1)} >
Decrement
</button>
</div>
);
}
export default CounterApp;
In both cases output remains the same but the implementation of states is different.
Conclusion
Hooks can cover all use cases for classes while providing more flexibility in extracting, testing, and reusing code. However, one reason you should still go for Class components over Functional components with hooks suspense is out of data fetching. Data fetching with useEffect
hook isn’t as intuitive as it is with lifecycle methods.
Hooks require a fraction of the code for simple components and seem excellent for optimizing HOCs. Meanwhile classes seem better with routing, container components and asynchronous programming for example.
💻 Happy Coding!
Posted on September 22, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.