✨ Introducing to you: new hooks 🐺 - Authentication and Forms made easy.


useAbortController

A hook that provides AbortController functionality for canceling asynchronous operations.

Abort Controller Demo
Demonstrates canceling HTTP requests using AbortController
Status:Idle

Quick Fetch: Fast request that completes immediately

Long Fetch: 5-second delay to test cancellation

Abort: Cancel the current request

Reset: Create a new controller and clear state

Auto-abort: Requests are automatically aborted when component unmounts

Installation

Options

PropTypeDefaultDescription
abortOnUnmountbooleantrueWhether to automatically abort when component unmounts

Data

The hook returns an object with the following properties:

PropertyTypeDescription
controllerAbortControllerThe AbortController instance
signalAbortSignalThe AbortSignal for passing to abortable operations
abortedbooleanWhether the controller has been aborted
abort(reason?: string) => voidFunction to abort the current controller
reset() => voidFunction to create a new controller (reset)
fetch(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>Convenience function for fetch with abort signal

Key Features & Details

Browser Support

  • Chrome: Full support (66+)
  • Firefox: Full support (57+)
  • Safari: Full support (11.1+)
  • Edge: Full support (79+)
  • Opera: Full support (53+)

Cross-Browser Compatibility

  • Native AbortController support in all modern browsers
  • Automatically handles signal.aborted checks
  • Graceful error handling for AbortError
  • Works with any API that accepts AbortSignal

Performance Considerations

  • Uses useRef to maintain controller instance across re-renders
  • useCallback optimizations for stable function references
  • Automatic cleanup on component unmount
  • Minimal memory footprint with proper controller disposal
  • No unnecessary re-renders when aborting operations

Best Practices & Caveats

  1. Always handle AbortError: Check error.name === 'AbortError' in catch blocks to distinguish between cancellation and actual errors
  2. Use reset() for new operations: Call reset() when starting a new operation to ensure a fresh controller
  3. Leverage the fetch wrapper: Use the provided fetch function for automatic signal attachment
  4. Component unmount handling: The hook automatically aborts operations when the component unmounts (configurable)
  5. Timeout patterns: Combine with setTimeout and clearTimeout for implementing request timeouts

Examples

Basic Usage

import { useAbortController } from '@/hooks/guarahooks/use-abort-controller';
 
function MyComponent() {
  const { signal, abort, fetch } = useAbortController();
 
  const handleFetch = async () => {
    try {
      const response = await fetch('/api/data');
      const data = await response.json();
      console.log(data);
    } catch (error) {
      if (error.name === 'AbortError') {
        console.log('Request was cancelled');
      } else {
        console.error('Request failed:', error);
      }
    }
  };
 
  return (
    <div>
      <button onClick={handleFetch}>Fetch Data</button>
      <button onClick={() => abort()}>Cancel</button>
    </div>
  );
}

Advanced Usage with Timeout

import { useEffect } from 'react';
 
import { useAbortController } from '@/hooks/guarahooks/use-abort-controller';
 
function MyComponent() {
  const { signal, abort, reset } = useAbortController();
 
  const fetchWithTimeout = async (url: string, timeout = 5000) => {
    // Reset controller for new request
    reset();
 
    // Set up timeout
    const timeoutId = setTimeout(() => {
      abort('Request timeout');
    }, timeout);
 
    try {
      const response = await fetch(url, { signal });
      clearTimeout(timeoutId);
      return await response.json();
    } catch (error) {
      clearTimeout(timeoutId);
      throw error;
    }
  };
 
  return (
    <button onClick={() => fetchWithTimeout('/api/slow-endpoint')}>
      Fetch with 5s timeout
    </button>
  );
}

With Options

import { useAbortController } from '@/hooks/guarahooks/use-abort-controller';
 
function MyComponent() {
  // Disable auto-abort on unmount
  const { signal, abort } = useAbortController({
    abortOnUnmount: false,
  });
 
  const handleLongRunningOperation = async () => {
    try {
      // This won't be automatically cancelled when component unmounts
      const response = await fetch('/api/long-process', { signal });
      return await response.json();
    } catch (error) {
      if (error.name === 'AbortError') {
        console.log('Operation was manually cancelled');
      }
    }
  };
 
  return (
    <div>
      <button onClick={handleLongRunningOperation}>Start Operation</button>
      <button onClick={() => abort('User cancelled')}>Cancel</button>
    </div>
  );
}