Open In App

How to handle asynchronous operations in custom hooks?

Last Updated : 23 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Custom Hooks in React are reusable JavaScript functions that enable the encapsulation of stateful logic, promoting cleaner and more modular code in components. When dealing with asynchronous operations in custom hooks, you want to ensure your hook can handle tasks that don’t finish immediately, like fetching data from a server or waiting for a user interaction.

Simple Approach to Handle Asynchronous operation:

  • Initial Setup: Start by setting up your custom hook function. This function will encapsulate the asynchronous operation.
  • State Management: Utilize React’s useState hook to manage the state of your asynchronous operation. This typically involves having a state variable to hold the result of the asynchronous operation and a loading state to indicate when the operation is still in progress.
  • Effect Hook for Asynchronous Operation: Inside your custom hook, use the useEffect hook to perform the asynchronous operation. This hook allows you to execute code after the component (or hook) has been rendered. Within the effect, you can make your asynchronous call, update the state accordingly, and handle any errors that may occur.
  • Return Values: Finally, return any necessary values from your custom hooks, such as the data retrieved from the asynchronous operation and any functions to trigger or control that operation.

Example: This is a simple example to handle asynchronous operations in custom hooks.

  • The useAsyncData hook handles asynchronous data fetching from a specified URL, managing loading and error states using useState and useEffect.
  • The App component utilizes the useAsyncData hook to render a list of items when data is successfully loaded, while also displaying loading or error messages if loading fails or an error occurs.

Javascript




import React, {
    useState,
    useEffect
}
    from 'react';
 
// Custom hook for fetching data asynchronously
const useAsyncData = (url) => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
 
    useEffect(() => {
        async function fetchData() {
            try {
                setLoading(true);
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(
                        'Network response was not ok');
                }
                const jsonData = await response.json();
                setData(jsonData);
            } catch (error) {
                setError(error);
            } finally {
                setLoading(false);
            }
        }
 
        fetchData();
        return () => {
        };
    }, [url]);
    /*
     Depend on url so that useEffect
     runs whenever the url changes
    */
 
    return { data, loading, error };
}
 
const App = () => {
    const { data, loading, error } =
        useAsyncData('https://fakestoreapi.com/products');
 
    if (loading) {
        return <div>Loading...</div>;
    }
 
    if (error) {
        return <div>Error: {error.message}</div>;
    }
 
    return (
        <div>
            {/* Render your data */}
            {data && (
                <ul>
                    {data.map(item => (
                        <li key={item.id}>
                            {item.title}
                        </li>
                    ))}
                </ul>
            )}
        </div>
    );
}
 
export default App;


Output:

gfg39

Ouput



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads