'React-Query: How to useQuery when button is clicked
I am new to this react-query library.
I know that when I want to fetch data, with this library I can do something like this:
const fetchData = async()=>{...}
// it starts fetching data from backend with this line of code
const {status, data, error} = useQuery(myKey, fetchData());
It works. But how to trigger the data fetching only when a button is clicked? , I know I probably could do something like <Button onPress={() => {useQuery(myKey, fetchData())}}/> , but how to manage the returned data and status...
Solution 1:[1]
According to the API Reference, you need to change the enabled option to false to disable a query from automatically running. Then you refetch manually.
// emulates a fetch (useQuery expects a Promise)
const emulateFetch = _ => {
return new Promise(resolve => {
resolve([{ data: "ok" }]);
});
};
const handleClick = () => {
// manually refetch
refetch();
};
const { data, refetch } = useQuery("my_key", emulateFetch, {
refetchOnWindowFocus: false,
enabled: false // disable this query from automatically running
});
return (
<div>
<button onClick={handleClick}>Click me</button>
{JSON.stringify(data)}
</div>
);
Working sandbox here
Bonus: you can pass anything that returns a boolean to enabled.
That way you could create Dependant/Serial queries.
// Get the user
const { data: user } = useQuery(['user', email], getUserByEmail)
// Then get the user's projects
const { isIdle, data: projects } = useQuery(
['projects', user.id],
getProjectsByUser,
{
// `user` would be `null` at first (falsy),
// so the query will not execute until the user exists
enabled: user,
}
)
Solution 2:[2]
Looks like the documentation changed and is missing the manual querying section right now. Looking at the useQuery API however, you'd probably need to set enabled to false, and then use refetch to manually query when the button is pressed. You also might want to use force: true to have it query regardless of data freshness.
Solution 3:[3]
You have to pass the manual: true parameter option so the query doesn't fetch on mount. Also, you should pass fetchData without the parentheses, so you pass the function reference and not the value.
To call the query you use refetch().
const {status, data, error, refetch} = useQuery(myKey, fetchData, {
manual: true,
});
const onClick = () => { refetch() }
Refer to the manual querying section on the react-query docs for more info https://github.com/tannerlinsley/react-query#manual-querying
Solution 4:[4]
There is another way to do this that also works if you want to trigger multiple refetches.
const [fetch, setFetch] = useState(null);
const query = useQuery(["endpoint", fetch], fetchData);
const refetch = () => setFetch(Date.now());
// call the refetch when handling click.
If you want to refetch multiple entities you could have a top level useState that is called for instance fetchAll and:
...
const query = useQuery(["endpoint", fetch, fetchAll], fetchData);
...
and this code will also trigger if you press a button to fetch all.
Solution 5:[5]
You can try this version:
const fetchData = async()=>{...}
// it starts fetching data from backend with this line of code
const {status, data, error, refetch } = useQuery(
myKey,
fetchData(),
{
enabled: false,
}
);
const onClick = () => { refetch() }
// then use onClick where you need it
From documentation Doc:
enabled: boolean
- Set this to false to disable this query from automatically running.
- Can be used for Dependent Queries.
refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise<UseQueryResult>
- A function to manually refetch the query.
- If the query errors, the error will only be logged. If you want an error to be thrown, pass the
throwOnError: true option - If
cancelRefetchistrue, then the current request will be cancelled before a new request is made
Solution 6:[6]
At first react query gives us enabled option and by default it is true
const fetchData = async()=>{...}
const {status, data, error , refetch} = useQuery(myKey, fetchData() , {
enabled : false
}
);
<button onClick={() => refetch()}>Refetch</button>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Esxiel |
| Solution 3 | Kevin Gelpes |
| Solution 4 | |
| Solution 5 | Vitalii Andrusishyn |
| Solution 6 | Build Though |
