ReactJS Custom Hooks

25 Oct, 2020
React.Js provides lots of built-in hooks that you can use in your React apps. But besides them, you can make your own custom hooks and use it in your apps resulting in better readability and a reduced amount of code. Custom hooks are normal JavaScript functions whose names start with “use” and they may call other hooks(built-in or custom). 
The need for Custom Hooks: The main reason for which you should be using Custom hooks is to maintain the concept of DRY(Don’t Repeat Yourself) in your React apps. For example, suppose you have some logic that makes use of some built-in hooks and you need to use the logic in multiple functional components. So, there are two ways left for you — 1) write the same logic in each and every component (which violates the concept of DRY) and 2) create a separate function that wraps the logic inside it and then call it from those components. The second option is undoubtedly a better choice as you have to write the logic only once. Here, the separate function you created is the custom hook. So, whenever you feel that you have a logic that is to be used in multiple functional components(hooks don’t work in class components), just create a separate custom hook for it and use it.
Building a custom hook: Creating a custom hook is the same as creating a JavaScript function whose name starts with “use”. It can use other hooks inside it, return anything you want it to return, take anything as parameters. The function “useCustomHook” in the below example, is a custom hook that uses a state variable “counter”. The function “resetCounter” increases the value of counter by 1 and whenever the value of the counter updates, the function passed to the useEffect hook is called.  The function executes some code(removed as to focus on how to use custom hooks rather than implementing a logic) that will be used in multiple components. This custom hook returns the “resetCounter” function.
Filename- src/useCustomHook.js:
Javascript
import {useState , useEffect} from "react";  // Remember to start the name of your custom hook with "use"function useCustomHook(initializer , componentName){    const [counter , setCounter] = useState(initializer);          // Increases the value of counter by 1       function resetCounter(){        setCounter(counter + 1);    }            useEffect(() => {        // Some logic that will be used in multiple components        console.log("The button of the "         + componentName + " is clicked "        + counter + " times.");    } , [counter , componentName]);           // Calls the useEffect hook if the counter updates    return resetCounter;}  export default useCustomHook;
Using the custom hook in components: To use the custom hook in your components just import the “useCustomHook” function from “useCustomHook.js” file in the “src” folder.
Filename- src/components/FirstComponent.js:
Javascript
import React from "react";  // importing the custom hookimport useCustomHook from "../useCustomHook";  function FirstComponent(props){      // ClickedButton = resetCounter;    const clickedButton = useCustomHook(0 , "FirstComponent");           return (        <div>            <h1> This is the First Component</h1>            <button onClick={clickedButton}>                   Click here!            </button>        </div>    );}  export default FirstComponent;
Filename : src/components/SecondComponent.js:
Javascript
import React from "react";  // Importing the custom hookimport useCustomHook from "../useCustomHook";  function SecondComponent(props){      // ClickedButton = resetCounter;    const clickedButton = useCustomHook(0 , "SecondComponent");           return (        <div>            <h1> This is the Second Component</h1>            <button onClick={clickedButton}>                Click here!            </button>        </div>    );}  export default SecondComponent;
Filename: src/App.js:
Javascript
import React from 'react';import './App.css';import FirstComponent from './components/FirstComponent';import SecondComponent from './components/SecondComponent';  function App(){     return(         <div className='App'>         <FirstComponent />        <SecondComponent />        </div>     );}     export default App;
Output: 
If you open the console of your browser, you will see: 
Note that the useEfffect is called after the first render even though we declare the dependency array. That means the callback function passed to the useEffect hook is executed after the first render and when the variables in the dependency array get updated. There is no straight way to prevent this first execution.
Now, if you click the first button(button of the FirstComponent) and check the console, you will see that each time you click on the button, the value of the counter increases by 1, and the updated value is printed on the console.
If you click the second button, it will be similar to the above output, carefully check the console:
Note that both the counters (defined in “usecustomHook”) of the two components are different. The two components use two different “counter” state variable(see “useCustomhook.js”), they don’t share the states. Therefore, in this React app, each component has its own “counter” state variable. Similarly, each component has its own useEffect and they are executed independently of each other. If the counter of the FirstComponent is updated, the useEffect of the FirstComponent is called, similarly if the counter of the SecondComponent is updated, the useEffect of the SecondComponent is called independently of the FirstComponent (See the above output). 
In the “src/components/FirstComponent.js” the code is equivalent to the below code: 
Javascript
import React , {useState ,useEffect} from "react";  function FirstComponent(props){          const [counter , setCounter] = useState(initializer);          // Increases the value of counter by 1       function resetCounter(){        setCounter(counter + 1):    }          useEffect(() => {        // Some logic         console.log(counter);    } , [counter]);          const clickedButton = resetCounter;           return (        <div>            <h1> This is the First Component</h1>            <button onClick={clickedButton}>                Click here!            </button>        </div>    );}  export default FirstComponent;
Note: It is important to name your custom hooks starting with “use”, because without it React can’t realize that it is a custom hook and therefore can’t apply the rules of hooks to it. So, you should name it starting with “use”.
react-js
JavaScript
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.