updated service binders updated
This commit is contained in:
@@ -1,181 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Cache options for the fetch request
|
||||
*/
|
||||
export type CacheOptions = {
|
||||
/** Whether to cache the request (default: true) */
|
||||
cache?: boolean;
|
||||
/** Revalidate time in seconds (if not provided, uses Next.js defaults) */
|
||||
revalidate?: number;
|
||||
/** Force cache to be revalidated (equivalent to cache: 'no-store' in fetch) */
|
||||
noStore?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request options for the fetch
|
||||
*/
|
||||
export type FetchOptions = {
|
||||
/** HTTP method (default: 'GET') */
|
||||
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
||||
/** Request headers */
|
||||
headers?: HeadersInit;
|
||||
/** Request body (for POST, PUT, PATCH) */
|
||||
body?: any;
|
||||
};
|
||||
|
||||
/**
|
||||
* A hook for fetching data from an API endpoint without pagination using Next.js fetch
|
||||
* @param url The API endpoint URL
|
||||
* @param initialParams Initial query parameters
|
||||
* @param options Additional fetch options
|
||||
* @param cacheOptions Cache control options
|
||||
* @returns Object containing data, loading state, error state, and refetch function
|
||||
*/
|
||||
export function useStandardApiFetch<T>(
|
||||
url: string,
|
||||
initialParams: Record<string, any> = {},
|
||||
options: FetchOptions = {},
|
||||
cacheOptions: CacheOptions = { cache: true }
|
||||
) {
|
||||
const [data, setData] = useState<T | null>(null);
|
||||
const [params, setParams] = useState<Record<string, any>>(initialParams);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
/**
|
||||
* Builds the URL with query parameters
|
||||
*/
|
||||
const buildUrl = () => {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
// Add all non-null and non-empty params
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== null && value !== '') {
|
||||
queryParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
|
||||
const queryString = queryParams.toString();
|
||||
return queryString ? `${url}?${queryString}` : url;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure fetch options including cache settings
|
||||
*/
|
||||
const getFetchOptions = (): RequestInit => {
|
||||
const { method = 'GET', headers = {}, body } = options;
|
||||
|
||||
const fetchOptions: RequestInit = {
|
||||
method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...headers,
|
||||
},
|
||||
};
|
||||
|
||||
// Add body for non-GET requests if provided
|
||||
if (method !== 'GET' && body) {
|
||||
fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
|
||||
}
|
||||
|
||||
// Configure cache options
|
||||
if (!cacheOptions.cache) {
|
||||
fetchOptions.cache = 'no-store';
|
||||
} else if (cacheOptions.noStore) {
|
||||
fetchOptions.cache = 'no-store';
|
||||
} else if (cacheOptions.revalidate !== undefined) {
|
||||
fetchOptions.next = { revalidate: cacheOptions.revalidate };
|
||||
}
|
||||
|
||||
return fetchOptions;
|
||||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const fullUrl = buildUrl();
|
||||
const fetchOptions = getFetchOptions();
|
||||
|
||||
const response = await fetch(fullUrl, fetchOptions);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
const responseData = await response.json();
|
||||
setData(responseData);
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err : new Error('An unknown error occurred'));
|
||||
setData(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, [url, JSON.stringify(params), JSON.stringify(options), JSON.stringify(cacheOptions)]);
|
||||
|
||||
/**
|
||||
* Update the query parameters and trigger a refetch
|
||||
* @param newParams New parameters to merge with existing ones
|
||||
*/
|
||||
const updateParams = (newParams: Record<string, any>) => {
|
||||
// Filter out null or empty string values
|
||||
const filteredParams = Object.entries(newParams).reduce((acc, [key, value]) => {
|
||||
if (value !== null && value !== '') {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {} as Record<string, any>);
|
||||
|
||||
setParams(prev => ({
|
||||
...prev,
|
||||
...filteredParams
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset all parameters to initial values
|
||||
*/
|
||||
const resetParams = () => {
|
||||
setParams(initialParams);
|
||||
};
|
||||
|
||||
/**
|
||||
* Manually trigger a refetch of the data
|
||||
*/
|
||||
const refetch = () => {
|
||||
fetchData();
|
||||
};
|
||||
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
updateParams,
|
||||
resetParams,
|
||||
refetch
|
||||
};
|
||||
}
|
||||
|
||||
// // Basic usage (with default caching)
|
||||
// const { data, loading, error, refetch } = useStandardApiFetch<schema.YourDataType>('/api/your-endpoint');
|
||||
|
||||
// // With no caching (for data that changes frequently)
|
||||
// const { data, loading, error, refetch } = useStandardApiFetch<schema.YourDataType>(
|
||||
// '/api/your-endpoint',
|
||||
// {},
|
||||
// {},
|
||||
// { cache: false }
|
||||
// );
|
||||
|
||||
// // With specific revalidation time
|
||||
// const { data, loading, error, refetch } = useStandardApiFetch<schema.YourDataType>(
|
||||
// '/api/your-endpoint',
|
||||
// {},
|
||||
// {},
|
||||
// { revalidate: 60 } // Revalidate every 60 seconds
|
||||
// );
|
||||
Reference in New Issue
Block a user