What are React hooks?
When we use React class components, we used to manage state and other React lifecycle features inside those class components using React lifecycle methods like ”componentDidMount”.
Since React brought us functional component features, it needed to have those lifecycle methods same as the React class components. Therefore, Hooks are functions that let you “hook into” React state and lifecycle features from function components same as the class components.
To get to know more details about React life cycle, visit React Component Life Cycle post.
Hooks we should use in different stages of React Life Cycle?
As we know React life cycle can be divided in to 3 main stages according to how the component renders to the DOM respectively mounting, Updating and Unmounting from the DOM. Let’s understand most commonly use hooks.
useState
To update the state of a React function component we need to use "useState" hook. As shown in the below code block, we need to import it as a named import before we use it.
This “useState” hook takes only one parameter as the initial state of the component and returns two values, the current state of the component (“count” in the below component) and a function (“setCount” in the below component) to update the state.
js
import React, { useState } from "react";function CountMe() {const [count, setCount] = useState(0);const increment = () => {setCount((previous) => {return previous + 1;});};const decrement = () => {setCount((previous) => {return previous - 1;});};return (<div><h1>Count : {count}</h1><button onClick={increment}> + </button><button onClick={decrement}> - </button></div>);}export default CountMe;
Using the setCount function we can update our state as we want. In this above code, setCount is used to increase and decrease the state “count”. Passing a callback function to this state changing function we can get the previous state as an argument of this callback function. This is the way that CountMe component gets the previous state and every time we call this “setCount” function, the render method of this CountMe component gets called and render the element with updated state.
useEffect
This function can perform the most part of react life cycle. Simply we can say that this function can use for same purpose as “componentDidMount”, “componentDidUpdate”, and “componentWillUnmount” in React classes.
Basically, we use this to perform side effects like data fetching, event subscriptions in React function component.
js
import React, { useState, useEffect } from "react";function CountMe() {const [count, setCount] = useState(0);const increment = () => {setCount((previous) => {return previous + 1;});};const decrement = () => {setCount((previous) => {return previous - 1;});};useEffect(() => {alert("Run on mounting of <CountMe/> ");}, []);useEffect(() => {alert(`Run on initial & update of count state : ${count}`);}, [count]);return (<div><h1>Count : {count}</h1><button onClick={increment}> + </button><button onClick={decrement}> - </button></div>);}export default CountMe;
This function takes two parameters. First one is a function and the second one is an array of dependencies. React runs the effects after every render including the first render. But we can avoid it using dependencies.
To perform “componentDidMount”, all we need to call this function with what we need to do as the first parameter and we can ignore the second parameter snice we need to run it on component mount.
If we need to execute any code block when the component’s state is updated, all we need to do is add the state value which is going to update in the dependency as shown in the code above in the second “useEffect”. So, the code inside the “useEffect” will run every time the “count” is going to update.
Note : if we use “useEffect” without the dependency array, at this time “useEffect” will run every update. To specifically run the “useEffect” on a state update, we need to add that variable to the array. At that time “useEffect” will only run according to the given dependencies. Also, “useEffect” will run only once when use an empty dependency array “[]”.
js
import React, { useEffect } from "react";function CountMe() {const scrollingMe = () => console.log("scrolling");useEffect(() => {window.addEventListener("scroll", scrollingMe);//Cleanup the EventListenerreturn () => window.removeEventListener("scroll", scrollingMe);}, []);return (<div style={{ height: "100vh" }}><h1>Scroll me and check the console</h1></div>);}
Sometimes, we need to subscribe for some event listeners when the component is mounted to the DOM and also we need to unsubscribe when the component is unmounted from the DOM. In React class components we used “componentDidMount” and “componentWillUnmount” to perform these kind of scenarios.
We can use “useEffect” hook to subscribe and unsubscribe these events like above by adding return statement. It means if we want to do something on component unmount, we can put that code part inside return statement like above code.
Creating your own hook
React has given the capability of creating our own hook to keep the code DRY (Don’t Repeat Yourself) by creating reusable functionalities as a custom hook. Check the post React Custom Hooks for more details.