Replies: 4 comments 9 replies
-
Why not use a wrapper over axios and add the timeout there. That's what I do in my projects at least. I use fetch and since my API has a specific structure (like always using problem details for non-2XX responses, see RFC 7807), I have a wrapper over fetch to handle all http response errors and client side errors like network issues in a unified way. In that wrapper I also include a custom delay. |
Beta Was this translation helpful? Give feedback.
-
While interceptors (read wrapper) are useful, they aren't the right place for granular control over loading times, especially considering background fetches. Also, if I moved the delay to interceptors or just to the service itself, it would limit reusability across different queries, as I wouldn't be able to easily customise the delay duration. Your proposal makes sense, but I value having control per query which this proposal promotes. |
Beta Was this translation helpful? Give feedback.
-
I'm turning my comment into an answer. A comment said that the API should not consider UI updates and I was convinced since the solution is much more controlled when using a throttle. The problem I have with iliasbhal's solution is that it also delays showing the loading UI. This is my solution which ensures that when we initiate a query/promise, the loading icon is shown asap, however if the query/promise has resolved, the loading state will be shown for at least a threshold. In my opinion, 200ms is a long enough time to communicate to the user that the application has done the work. I'm using Mantine as my component library, so I'm using their hooks. https://mantine.dev/hooks/use-throttled-value/. Otherwise you can use https://usehooks.com/usethrottle const { loading: accountLoading, ... } = YOUR_OBJECT;
const accountLoadingDelayed = useThrottledValue(accountLoading, accountLoading ? 400 : 0); |
Beta Was this translation helpful? Give feedback.
-
I solved this by writing a small utility function that wraps the fetch call to enforce a minimum waiting time. In my experience, just throttling the loading state isn’t enough - for example, with useMutation, the onSuccess or onError callbacks will still fire immediately, even if the loading state is throttled. By delaying the function itself, you ensure that both the UI state and lifecycle callbacks stay consistent. export function delayedFunction<T extends (...args: any[]) => any>(
fn: T,
ms: number
): T {
return (async (...args: Parameters<T>) => {
const startTime = Date.now();
const result = await fn(...args);
const elapsedTime = Date.now() - startTime;
const remainingTime = Math.max(0, ms - elapsedTime);
if (remainingTime > 0) {
await new Promise((resolve) => setTimeout(resolve, remainingTime));
}
return result;
}) as T;
} Usage // Query example
const { data, isLoading, error } = useQuery({
queryKey: ['exampleQuery'],
queryFn: delayedFunction(getData, 1000),
});
// Mutation example
const { mutate, isPending } = useMutation({
mutationFn: delayedFunction(saveData, 1000),
onError: (error) => {
console.error("Error saving data:", error);
},
onSuccess: (response) => {
console.log("Data saved successfully", response);
}
}); This way, you get consistent UX for both queries and mutations without having to repeat delay logic inside every function. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I want to ensure a minimum loading time for API requests to:
Current Workarounds
Existing solutions usually involve custom modifications to the query function to artificially add a delay using
setTimeout
or delay operators. These workarounds require repetitive code within each query.Example usage:
Previous Discussions
This feature request, regarding its use with the useMutation hook, has been mentioned before but without a solution:
Is it possible to have a minimum loading time for useMutation hook? #5428
Proposed Solution
Add an optional minLoadingDuration parameter to query options, working as follows:
Example usage
Let me know if you'd like this proposal, want me to refine this further or help with a draft implementation.
Beta Was this translation helpful? Give feedback.
All reactions