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?
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.