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
Prop | Type | Default | Description |
---|---|---|---|
abortOnUnmount | boolean | true | Whether to automatically abort when component unmounts |
Data
The hook returns an object with the following properties:
Property | Type | Description |
---|---|---|
controller | AbortController | The AbortController instance |
signal | AbortSignal | The AbortSignal for passing to abortable operations |
aborted | boolean | Whether the controller has been aborted |
abort | (reason?: string) => void | Function to abort the current controller |
reset | () => void | Function 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
- Always handle AbortError: Check
error.name === 'AbortError'
in catch blocks to distinguish between cancellation and actual errors - Use reset() for new operations: Call
reset()
when starting a new operation to ensure a fresh controller - Leverage the fetch wrapper: Use the provided
fetch
function for automatic signal attachment - Component unmount handling: The hook automatically aborts operations when the component unmounts (configurable)
- Timeout patterns: Combine with
setTimeout
andclearTimeout
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>
);
}