JAVASCRIPT

Handle Asynchronous Operations (e.g., Data Fetching) with React useAsync Hook

A robust custom React hook to manage the lifecycle of asynchronous operations, providing loading, error, and data states for API calls.

import { useState, useEffect, useCallback } from 'react';

function useAsync(asyncFunction, immediate = true) {
  const [status, setStatus] = useState('idle');
  const [value, setValue] = useState(null);
  const [error, setError] = useState(null);

  // The asyncFunction is wrapped in useCallback to avoid unnecessary re-renders
  // if it's passed directly from a parent component.
  const execute = useCallback(async () => {
    setStatus('pending');
    setValue(null);
    setError(null);
    try {
      const response = await asyncFunction();
      setValue(response);
      setStatus('success');
    } catch (err) {
      setError(err);
      setStatus('error');
    }
  }, [asyncFunction]);

  // Call execute immediately if desired
  useEffect(() => {
    if (immediate) {
      execute();
    }
  }, [execute, immediate]);

  return { execute, status, value, error };
}

export default useAsync;

// Example Usage:
// const fetchData = async () => {
//   const response = await fetch('https://api.example.com/data');
//   if (!response.ok) {
//     throw new Error('Failed to fetch data');
//   }
//   return response.json();
// };
//
// function DataComponent() {
//   const { execute, status, value, error } = useAsync(fetchData, true); // immediate fetch
//
//   if (status === 'pending') return <div>Loading...</div>;
//   if (status === 'error') return <div>Error: {error.message}</div>;
//   if (status === 'success') return <div>Data: {JSON.stringify(value)}</div>;
//
//   return <button onClick={execute}>Refetch Data</button>;
// }
How it works: The `useAsync` hook simplifies the management of asynchronous operations like API calls. It returns an `execute` function to trigger the operation and provides `status` ('idle', 'pending', 'success', 'error'), `value` (the resolved data), and `error` states. It can execute immediately upon component mount or be triggered manually, offering a structured way to handle loading, success, and error states in your UI.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs