e5f41731ae
* bootstrap next app + add overview page * fix AssetList type * fix up nav stuff * Refactor Nav component and add network components pages * Refactor WorldMap component and update TelegramIcon, GitHubIcon, NymVpnIcon, DiscordIcon, and TwitterIcon components * add service providers page * mixnodes page * delegations page + use material react table for all tables * nodes map page * Refactor StyledLink component and remove unnecessary console.log statements * Refactor ESLint configuration, remove unused dependencies, and update component imports * update deps * Refactor imports and update dependencies * fix dark mode * build single mixnode page * build single gateway page * Refactor handleOnDelegate function to use useCallback in mixnodes page.tsx * Add defaults for constants --------- Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
'use client'
|
|
|
|
import * as React from 'react';
|
|
import { ApiState } from '@/app/typeDefs/explorer-api';
|
|
|
|
/**
|
|
* Custom hook to get data from the API by passing an id to a delegate method that fetches the data asynchronously
|
|
* @param id The id to fetch
|
|
* @param fn Delegate the fetching to this method (must take `(id: string)` as a parameter)
|
|
* @param errorMessage A static error message, to use when no dynamic error message is returned
|
|
*/
|
|
export const useApiState = <T>(
|
|
id: string,
|
|
fn: (argId: string) => Promise<T>,
|
|
errorMessage: string,
|
|
): [ApiState<T> | undefined, () => Promise<ApiState<T>>, () => void] => {
|
|
// stores the state
|
|
const [value, setValue] = React.useState<ApiState<T>>();
|
|
|
|
// clear the value
|
|
const clearValueFn = () => setValue(undefined);
|
|
|
|
// this provides a method to trigger the delegate to fetch data
|
|
const wrappedFetchFn = React.useCallback(async () => {
|
|
setValue({ isLoading: true });
|
|
try {
|
|
// keep previous state and set to loading
|
|
setValue((prevState) => ({ ...prevState, isLoading: true }));
|
|
|
|
// delegate to user function to get data and set if successful
|
|
const data = await fn(id);
|
|
const newValue: ApiState<T> = {
|
|
isLoading: false,
|
|
data,
|
|
};
|
|
setValue(newValue);
|
|
return newValue;
|
|
} catch (error) {
|
|
// return the caught error or create a new error with the static error message
|
|
const newValue: ApiState<T> = {
|
|
error: error instanceof Error ? error : new Error(errorMessage),
|
|
isLoading: false,
|
|
};
|
|
setValue(newValue);
|
|
return newValue;
|
|
}
|
|
}, [setValue, fn, id, errorMessage]);
|
|
return [value, wrappedFetchFn, clearValueFn];
|
|
};
|