So far, we have discussed five different hooks in React:
useState
: For handling states.useReducer
: For handling more complex state logic.useContext
: For accessing and sharing data across components without prop drilling.useRef
: For directly interacting with DOM elements.useEffect
: For handling side effects, such as data fetching or updating the DOM after rendering.
Creating your custom hook
Besides these built-in hooks, sometimes you may need a hook for more specific purposes, such as fetching data, tracking window sizes, connecting to WebSocket servers, and more. Instead of repeating the same logic over and over again, React allows you to create custom hooks.
Let's go back to one of our previous examples:
1import { useState, useEffect } from "react";
2
3export default function App() {
4 const [user, setUser] = useState([]);
5 const [loading, setLoading] = useState(true);
6
7 useEffect(() => {
8 async function fetchUser() {
9 const response = await fetch("https://randomuser.me/api/");
10 const data = await response.json();
11 setUser(data.results[0]);
12 setLoading(false);
13 }
14
15 fetchUser();
16 }, []);
17
18 if (loading) return <div>Loading user...</div>;
19
20 return (
21 <div>
22 <h1>
23 {user.name.first} {user.name.last}
24 </h1>
25 <p>Email: {user.email}</p>
26 <img src={user.picture.large} alt="User profile" />
27 </div>
28 );
29}
In this example, the user information is fetched from an API and used to update the user profile. However, what if your app needs to retrieve additional data from multiple APIs? In this case, you'll need a more flexible approach that allows your app to access data from different sources.
To achieve this, you can extract the data retrieval portion of our code, and create a custom hook like this:
libs/hooks.js
1import { useState, useEffect } from "react";
2
3function useFetchData(url) {
4 const [data, setData] = useState(null);
5 const [loading, setLoading] = useState(true);
6
7 useEffect(() => {
8 async function fetchData() {
9 const response = await fetch(url);
10
11 setData(await response.json());
12 setLoading(false);
13 }
14
15 fetchData();
16 }, [url]); // Add url as dependency
17
18 return { data, loading };
19}
20
21export { useFetchData };