Well you can build your entire application without custom hooks also, then why do we need it.
We need custom hook because –
- Code re-usability
- Code modularity
- Clean and organized code
- Preventing logic repetition i.e. following DRY principal
I know some of the above word might sound jargon to you , so let understand custom hook practically –
Creating a simple online offline notifier
Let’s say I have 2 component , A and B , and I want to check the online offline status in both the component. Its pretty obvious that I have to write same logic in both the components to check the status , so to prevent logic repetition ,I am gonna create one js file , where I will be writing logic and using it in both the components.
Simple. Now lets code .
useOnline.js
import React, { useEffect, useState } from "react"; const useOnline = () => { const [isOnline, setIsOnline] = useState(true); console.log("custom hook"); useEffect(() => { window.addEventListener("online", () => setIsOnline(true)); window.addEventListener("offline", () => setIsOnline(false)); }, []); return isOnline; }; export default useOnline;
A.jsx
import useOnline from "../utils/useOnline"; const A = () => { var isOnline = useOnline(); return loading ? ( <h2>Loading..</h2> ) : ( <div> <h2>{isOnline ? "🟢Online" : "🔴Offline"}</h2> </div> ); }; export default A;
And its done. You have created a custom hook , that checks online offline status.
Watch Video Instead
Create a hook to fetch api and return response
useFetch.js
This custom hooks take api url (get request) , fetch the response and returns data , loading status and the error.
Now while using in actually component, you can either extract all the 3 things or any one or two, its completely upto you.
import { useEffect, useState } from "react"; const useFetch = (url) => { const [data, setData] = useState(); const [loading, setLoading] = useState(false); async function getData() { setLoading(true); const response = await fetch(url); const result = await response.json(); setData(result); setLoading(false); } useEffect(() => { getData(); }, []); return { data, loading }; }; export default useFetch;
A.jsx (fetching github user data)
import useFetch from "../utils/useFetch"; const A = () => { const { data, loading } = useFetch("https://api.github.com/users"); return loading ? ( <h2>Loading..</h2> ) : ( <div> <h2>Github Users</h2> {data?.map((ele) => ( <li key={ele.id}>{ele.login}</li> ))} </div> ); }; export default A;
B.jsx (Fetch fake json data)
import useFetch from "../utils/useFetch"; const B = () => { const { data, loading } = useFetch( "https://jsonplaceholder.typicode.com/todos" ); return loading ? ( <h2>Loading...</h2> ) : ( <div> <h2>Fake json user</h2> {data?.map((ele) => ( <li key={ele.id}>{ele.title}</li> ))} </div> ); }; export default B;
App.jsx
import { useState } from "react"; import reactLogo from "./assets/react.svg"; import viteLogo from "/vite.svg"; import "./App.css"; import A from "./components/A"; import B from "./components/B"; function App() { const [count, setCount] = useState(0); return ( <> <A /> <B /> </> ); } export default App;
Conclusion
While building bigger application , its must to use custom hooks, since it not only make your application clean and readable, it prevents logic repetition, code optimization , hence making the job of developer easy.
Hence, start building custom hook from today
Thank you for ready.
Happy Learning!