
- Add useLoadingState hook for managing loading states - Add useDebounce hook for debouncing values/callbacks - Add useApiCall hook for API call management with error handling - Add usePagination hook for pagination logic - Create centralized hooks/index.ts for exports - Reduce code duplication across components
48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
|
|
interface LoadingState<T> {
|
|
data: T | null;
|
|
isLoading: boolean;
|
|
error: Error | null;
|
|
execute: (...args: any[]) => Promise<T>;
|
|
reset: () => void;
|
|
}
|
|
|
|
/**
|
|
* Custom hook for managing loading states with error handling
|
|
* Reduces boilerplate code for async operations
|
|
*/
|
|
export function useLoadingState<T>(
|
|
asyncFunction: (...args: any[]) => Promise<T>
|
|
): LoadingState<T> {
|
|
const [data, setData] = useState<T | null>(null);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<Error | null>(null);
|
|
|
|
const execute = useCallback(
|
|
async (...args: any[]): Promise<T> => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
const result = await asyncFunction(...args);
|
|
setData(result);
|
|
return result;
|
|
} catch (err) {
|
|
const error = err instanceof Error ? err : new Error('An error occurred');
|
|
setError(error);
|
|
throw error;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
},
|
|
[asyncFunction]
|
|
);
|
|
|
|
const reset = useCallback(() => {
|
|
setData(null);
|
|
setError(null);
|
|
setIsLoading(false);
|
|
}, []);
|
|
|
|
return { data, isLoading, error, execute, reset };
|
|
} |