I am displaying all my api requests errors in a toast.
In my code, I have separated concepts, moving the components logic to business/ui hooks.
In order to render a toast (an imperative component), I just do the following inside a functional component:
const toast = useToast(); // UI hook
toast.display(message, { type: "error", duration: 500 });
and, in order to connect to my api, I can use custom business hooks, for example:
const useRequestSomething() {
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const isRequesting = useRef(false);
const requestSomething = async (someParam, onSuccess = undefined, onError = undefined) => {
if (isRequesting.current) return;
isRequesting.current = true;
setIsLoading(true);
try {
const data = await api.requestSomething(someParam);
setData(data);
onSuccess?.();
} catch(err) {
onError?.(err);
}
setIsLoading(false);
isRequesting.current = false;
}
return {
data,
isLoading,
requestSomething
}
}
My main concern is the separation of concepts... I don't think it is a good idea to use the useToast() inside the this hook that is a container of my business logic... although it may be a good idea.
So, in order to handle errors, inside any component, I can do something like:
function MyComponent() {
const toast = useToast();
const { t } = useTranslation(); // i18n.js hook
const { data, isLoading, requestSomething } = useRequestSomething();
const handleOnPress = () => {
requestSomething("x", undefined, handleOnRequestSomethingError);
}
const handleOnRequestSomethingError = (err) => {
toast.display(t(err), { type: "error", duration: 500 });
}
... JSX
}
It seems that I have defined some kind of callback-based api with the business hook... what do you think about my implementation?
Is it an anti-pattern to handle errors this way (with callbacks) inside hooks?
What is the typical approach to handle this situations? (I cannot use useQuery, because of my backend)