@towns-protocol/react-sdk
Version:
React Hooks for Towns Protocol SDK
58 lines • 1.99 kB
JavaScript
import { useCallback, useState } from 'react';
/**
* Hook to create an action from a namespace.
* @internal
* @param namespace - The namespace to create the action from.
* @param fnName - The name of the action to create. Example: `Namespace.fnName`
* @param config - Configuration options for the action.
* @returns The action and its loading state.
*/
export const useAction = (namespace, fnName, config) => {
const [status, setStatus] = useState('idle');
const [error, setError] = useState();
const [data, setData] = useState();
const action = useCallback(async (...args) => {
if (!namespace) {
throw new Error(`useAction: namespace is undefined`);
}
const fn = namespace[fnName];
if (typeof fn !== 'function') {
throw new Error(`useAction: fn ${fnName} is not a function`);
}
setStatus('loading');
try {
const data = (await fn.apply(namespace, args));
setData(data);
setStatus('success');
config?.onSuccess?.(data);
return data;
}
catch (error) {
setStatus('error');
if (error instanceof Error) {
setError(error);
config?.onError?.(error);
}
// Let the caller handle the error
throw error;
}
finally {
setStatus('idle');
}
}, [config, fnName, namespace]);
return {
/** The action to execute. */
action,
/** The data returned by the action. */
data,
/** The error that occurred while executing the action. */
error,
/** Whether the action is pending. */
isPending: status === 'loading',
/** Whether the action is successful. */
isSuccess: status === 'success',
/** Whether the action is in error. */
isError: status === 'error',
};
};
//# sourceMappingURL=useAction.js.map