Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally calling an API using React-Query hook

I am using react-query to make API calls, and in this problem case I want to only call the API if certain conditions are met.

I have an input box where users enter a search query. When the input value is changed, a search server is called with the contents of the input as the search query ... but only if the input value is more than 3 chars long.

In my react component I'm calling:

const {data, isLoading} = useQuery(['search', searchString], getSearchResults);

And my getSearchResults function will, conditionally, make an API call.

const getSearchResults = async (_, searchString) => {
    if (searchString.length < 3)
        return {data: []}

    const {data}  = await axios.get(`/search?q=${searchString}`)
    return data;
}

We can't use a hook inside a conditional - so I put the condition into my API calling function.

This almost works. If I enter a short query string, there is no API request made and I get an empty array back for the data. Yay!

But - isLoading will flip to true briefly - even though there is no HTTP request being made. So my loading indicator shows when there is no actual network activity.

Am I misunderstanding how to best solve my use case, is there a way to enure that isLoading will return false if there is no HTTP activity?

like image 531
Tom Harvey Avatar asked Aug 13 '20 14:08

Tom Harvey


People also ask

Should I use react query or SWR?

So if you are building a simple application and want a ready-to-go simple solution then SWR should be your choice. But if you need more control and customization and want to get the most out of the developer tools then definitely go for react-query.

How do you Refetch a react query?

Using auto refetching in React Query To use the auto refetch mode, you can pass an optional parameter to the React Query hook called refetchInterval . The value is in milliseconds. const { isLoading, data } = useQuery( 'vehicle', async () => { const { data } = await axios.

Does react query use Fetch?

React Query is often described as the missing data-fetching library for React. Still, in more technical terms, it makes fetching, caching, synchronizing, and updating server state in your React applications a breeze.


1 Answers

The key was to use Dependent Queries

So, in my main component, I create a boolean and pass that to the enabled option of the useQuery hook:

const isLongEnough = searchString.length < 3;
const {data, isLoading} = useQuery(['search', searchString], getSearchResults, {enabled: isLongEnough});

and the API calling method is simply the API call - not any conditional:

const getSearchResults = async (_, searchString) => {
    const {data} = await axios.get(`/search?q=${searchString}`);
    return data;
}

The docs describe dependent queries as a solution for loading data from subsequent API endpoints, but the enable option can accept any boolean. In this case - if the search query string is long enough.

like image 72
Tom Harvey Avatar answered Sep 24 '22 14:09

Tom Harvey