What are React Hooks?
Introduction
Functional components were initially introduced as pure or stateless components, i.e., they could not offer a state to a compound. But with the introduction of Hooks in v16.8.0, functional components can also offer a state to a component without writing a class component for that reason.
So, what are React Hooks?
Here is how ‘React’ defines Hooks:
“Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.”
Hooks provide functional components with a state and a way to access react lifecycle methods, which means we can have all the features of a class component in a functional component. But what does a react hook looks like, and how it can bring state to a functional component? Let’s review a simple example.
Example of a React Hook
import ‘./App.css‘;
import { useState } from ‘react‘;
function React_Hooks() {
const [textColor, setTextColor] = useState(“green“);
function changeTextColor(){
if(textColor===“blue“)
setTextColor(“green“)
else
setTextColor(“blue“)
}
return (
<div className=“App“>
<header className=“App-header“>
<p className={textColor===“blue“ ? “blueText“ : “greenText“ } >
Hello, let’s learn a thing or two about React Hooks
</p>
<button onClick={()=>changeTextColor()}> Change Color</button>
</header>
</div>
);
}
export default React_Hooks;
We have used a state hook called “useState.”..” In this example, we initialized a state variable with a value (in our example, ‘green’) of type string. It shows we can initialize a state hook with a number, string, object, null or an array. This is different from class components, where we use “this.state,” which has to be an object.
const [textColor, setTextColor] = useState(“green”);
Using array destructuring syntax, we define our own state variables (textColor and setTextColor), which useState provides us with. useState returns an array with an initial value at the first index and a handler at the second index. textColor holds the initialized state value, and setTextColor is the handler, used to update the value of textColor like this.setState.
In our example, we have set the text color initially to green, but after pressing the “Change Color” button, changeTextColor() is called, which changes the text color using the handler setTextColor.
Motivation Behind Introducing Hooks
React hooks provide functional components with state(s) and other features, which were previously only available in the class component. This begs the question why there was a need, if class components were already in place to provide state(s) and all other features? So, in this section, we will discuss the reason and the motivation behind introducing hooks.
#1: Less Readability and Difficult Maintenance
Functional components were always preferred due to their conciseness and readability, which translates into cleaner code and is much easier to understand. This also helps us in testing and maintaining the code.
With the addition of new functionality or changing requirements, simple class components grow to become complex components with stateful logic in them. Functional components, on the other hand, offer a simpler framework with the ability to split components into distinct functions.
Here is a particularly good example from a blog written by Eric Bishard, which explains how readability is affected with functional components.
#2: Complex code
Class-based components have lifecycle methods. Most of these methods contains some related and unrelated logic at the same time. For example, in componentDidMount(), we are making API calls and at the same time setting up listeners. The same goes for other lifecycle methods, for example, componentWillUnmount(), etc. This level of coupling introduces complexity and difficulty in understanding the code.
In functional components, however, this logic does not have to be segregated forcefully by lifecycle methods. For example, you can have more than one useEffects() to perform different operations.
#3: Reuse and Share Stateful Logic
It wasn’t possible to reuse stateful logic or share it across different components with class components before. But with hooks, the users can build their own custom hooks and segregate the stateful logic from components to reuse and share it across the application.
Types of Hooks
The above example highlighted the use of useState hook. It is just one of the types. There are other types of hooks as well.
Here are a few types of hooks:
- State Hook – useState: The useState is a React hook used for
object state management.
- Effect Hook – useEffect: The useEffect is used to execute certain actions upon certain effects.
- Other Hooks
- useContext: The useContext hook creates the specific context state object by using the ContextObject.
- useReducer: The useReducer hook is the most suitable when we have a complex state dependent on other states.
- useContext: The useContext hook creates the specific context state object by using the ContextObject.
- Custom Hooks: The custom hooks are an optimal option for the re-useability of stateful logic.
Other than the built-in hooks react offers, we can also opt for custom hooks. This comes in handy when we have to share the stateful logic amongst different components.
React Hooks Rule Book
Here are a few rules we need to abide by while working with react hooks.
React hooks should:
- Be called at the top level of the component.
- Never be called within loops, conditions, or nested functions.
- Only be called from functional components.
- Not be called from regular JavaScript functions.
Conclusion
In this blog, we covered the basics of React hooks along with shedding light on one of the most widely used hooks, the State Hook, with the help of an example (useState). Besides all the above-mentioned benefits, React hooks are backwards compatible, which means they can work side-by-side with class components.
We hope this blog helped you understand the what, why, and how of React Hooks. We will discuss other hooks, for example, useContext, etc., in other blogs soon!
Want to add something? Comment below; let’s grow together.