useAxios Hook Demo
Demonstrando as funcionalidades do hook useAxios com provider global, retry automático, abort controller e múltiplas requisições.
Installation
Usage
Wrap your app with AxiosProvider
import { AxiosProvider } from '@/hooks/use-axios';
function App() {
return (
<AxiosProvider config={{ baseURL: 'https://api.example.com' }}>
<YourApp />
</AxiosProvider>
);
}
Use the hook in your components
import { useAxiosGet } from '@/hooks/use-axios';
function UserProfile() {
const { data, loading, error } = useAxiosGet<User>('/users/me');
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{data?.name}</div>;
}
API Reference
AxiosProvider Props
Prop | Type | Default | Description |
---|
config | AxiosConfig | {} | Global configuration for all axios requests |
children | ReactNode | undefined | Child components that will use the provider |
AxiosConfig Interface
Property | Type | Default | Description |
---|
baseURL | string | undefined | Base URL for all relative requests |
timeout | number | undefined | Request timeout in milliseconds |
retries | number | 0 | Number of retry attempts on failure |
retryDelay | number | 1000 | Delay between retry attempts (ms) |
headers | Record<string, string> | undefined | Default headers for all requests |
method | string | 'GET' | Default HTTP method |
auth | AxiosBasicCredentials | undefined | Basic authentication credentials |
params | any | undefined | Default URL parameters |
data | any | undefined | Default request body |
useAxios Hook
function useAxios<T>(
config: AxiosRequestConfig & { immediate?: boolean },
): AxiosResult<T>;
Parameters
Parameter | Type | Default | Description |
---|
config | AxiosRequestConfig & { immediate?: boolean } | {} | Axios configuration and hook options |
AxiosOptions Interface
Property | Type | Default | Description |
---|
retries | number | undefined | Retry attempts (overrides global) |
retryDelay | number | undefined | Retry delay (overrides global) |
immediate | boolean | true | Whether to execute request immediately |
url | string | undefined | Request URL |
method | string | undefined | HTTP method |
data | any | undefined | Request body |
params | any | undefined | URL parameters |
headers | Record<string, string> | undefined | Request headers |
Return Value (AxiosResult)
Property | Type | Description |
---|
data | T | null | The fetched data or null on error/loading |
error | AxiosError | null | Error object if the request fails |
loading | boolean | Whether the request is in progress |
refetch | () => Promise<T | null> | Function to re-trigger the axios request |
abort | () => void | Cancels the current in-flight request |
aborted | boolean | Whether the request was aborted |
Convenience Hooks
useAxiosGet
function useAxiosGet<T>(url: string, config?: AxiosOptions): AxiosResult<T>;
useAxiosPost
function useAxiosPost<T>(
url: string,
data?: any,
config?: AxiosOptions,
): AxiosResult<T>;
useAxiosPut
function useAxiosPut<T>(
url: string,
data?: any,
config?: AxiosOptions,
): AxiosResult<T>;
useAxiosDelete
function useAxiosDelete<T>(url: string, config?: AxiosOptions): AxiosResult<T>;
useAxiosPatch
function useAxiosPatch<T>(
url: string,
data?: any,
config?: AxiosOptions,
): AxiosResult<T>;
useAxiosContext Hook
function useAxiosContext(): AxiosContextValue;
Access the global axios configuration and update it dynamically.
Return Value
Property | Type | Description |
---|
config | AxiosConfig | Current global configuration |
updateConfig | (config: Partial<AxiosConfig>) => void | Function to update global configuration |
instance | AxiosInstance | Axios instance |
request | <T>(config: AxiosRequestConfig) => Promise<AxiosResponse<T>> | Enhanced axios request function |
useAxiosInstance Hook
function useAxiosInstance(): AxiosInstanceMethods;
Access axios instance methods for manual requests.
Return Value
Property | Type | Description |
---|
instance | AxiosInstance | Raw axios instance |
request | <T>(config: AxiosRequestConfig) => Promise<AxiosResponse<T>> | Enhanced request function |
get | <T>(url: string, config?: AxiosRequestConfig) => Promise<AxiosResponse<T>> | GET request method |
post | <T>(url: string, data?: any, config?: AxiosRequestConfig) => Promise<AxiosResponse<T>> | POST request method |
put | <T>(url: string, data?: any, config?: AxiosRequestConfig) => Promise<AxiosResponse<T>> | PUT request method |
delete | <T>(url: string, config?: AxiosRequestConfig) => Promise<AxiosResponse<T>> | DELETE request method |
patch | <T>(url: string, data?: any, config?: AxiosRequestConfig) => Promise<AxiosResponse<T>> | PATCH request method |
Key Features
🌐 Global Provider
- Centralized configuration for all HTTP requests
- Shared settings like base URL, headers, timeouts
- Dynamic configuration updates at runtime
🔄 Automatic Retry
- Configurable retry attempts with exponential backoff
- Intelligent retry logic (skips client errors and cancellations)
- Per-request or global retry configuration
⏱️ Timeout Support
- Request-level and global timeout settings
- Automatic request cancellation on timeout
- Prevents hanging requests
🛑 Abort Control
- Manual request cancellation
- Automatic cleanup on component unmount
- Prevents memory leaks and race conditions
🎯 Type Safety
- Full TypeScript support with generics
- Type-safe request/response handling
- Intellisense for all configuration options
- Efficient memoization to prevent unnecessary re-renders
- Automatic request deduplication
- Optimized for React concurrent features
🔧 Axios Integration
- Full Axios feature support (interceptors, transformers, etc.)
- Request/response transformations
- Built-in JSON parsing and serialization
Examples
Basic GET Request
const { data, loading, error } = useAxiosGet<Post[]>('/posts');
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{data?.map((post) => (
<div key={post.id}>{post.title}</div>
))}
</div>
);
POST Request
const {
data,
loading,
refetch: createPost,
} = useAxiosPost<Post>(
'/posts',
{
title: 'New Post',
body: 'Post content',
userId: 1,
},
{
immediate: false,
},
);
return (
<button onClick={createPost} disabled={loading}>
{loading ? 'Creating...' : 'Create Post'}
</button>
);
Manual Requests with useAxiosInstance
const { get, post, loading } = useAxiosInstance();
const handleFetch = async () => {
try {
const response = await get<User[]>('/users');
console.log(response.data);
} catch (error) {
console.error('Request failed:', error);
}
};
return <button onClick={handleFetch}>Fetch Users</button>;
With Retry and Timeout
const { data, loading } = useAxiosGet<Data>('/api/data', {
retries: 3,
retryDelay: 2000,
timeout: 5000,
});
Abort Request
const { data, loading, abort } = useAxiosGet<Data>('/api/data');
return (
<div>
{loading && <button onClick={abort}>Cancel</button>}
{data && <div>{JSON.stringify(data)}</div>}
</div>
);
Dynamic Configuration
function AuthButton() {
const { updateConfig } = useAxiosContext();
const handleLogin = (token: string) => {
updateConfig({
headers: { Authorization: `Bearer ${token}` },
});
};
return <button onClick={() => handleLogin('token')}>Login</button>;
}
function UserForm() {
const [formData, setFormData] = useState({ name: '', email: '' });
const {
data,
loading,
error,
refetch: submitForm,
} = useAxiosPost<User>('/users', formData, { immediate: false });
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await submitForm();
};
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="Name"
/>
<input
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder="Email"
/>
<button type="submit" disabled={loading}>
{loading ? 'Submitting...' : 'Submit'}
</button>
{error && <div>Error: {error.message}</div>}
{data && <div>Success! User ID: {data.id}</div>}
</form>
);
}
Error Handling
const { data, error, refetch } = useAxiosGet<Data>('/api/data');
if (error) {
return (
<div>
<h3>Request Failed</h3>
<p>Status: {error.response?.status}</p>
<p>Message: {error.message}</p>
<button onClick={refetch}>Retry</button>
</div>
);
}
Best Practices
Provider Configuration
<AxiosProvider
config={{
baseURL: process.env.REACT_APP_API_URL,
timeout: 30000,
retries: 3,
retryDelay: 1000,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
}}
>
Loading States
const { data, loading, error } = useAxiosGet<Data>('/api/data');
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{data?.content}</div>;
Stable Dependencies
const requestData = useMemo(
() => ({
userId: user.id,
timestamp: Date.now(),
}),
[user.id],
);
const { data, loading } = useAxiosPost<Response>('/api/submit', requestData, {
immediate: false,
});
Authentication
function useAuth() {
const { updateConfig } = useAxiosContext();
const login = (token: string) => {
updateConfig({
headers: { Authorization: `Bearer ${token}` },
});
};
const logout = () => {
updateConfig({
headers: {},
});
};
return { login, logout };
}