React-Query: How to useQuery when button is clicked

Leem.fin picture Leem.fin · Jun 12, 2020 · Viewed 38.5k times · Source

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

Answer

Nicolas Hevia picture Nicolas Hevia · Jul 27, 2020

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 axios/fetch since useQuery expectes a Promise
const emulateFetch = _ => {
  return new Promise(resolve => {
    resolve([{ data: "ok" }]);
  });
};

const handleClick = () => {
  // manually refetch
  refetch();
};

const { data, refetch } = useQuery("key", emulateFetch, {
  refetchOnWindowFocus: false,
  enabled: false // turned off by default, manual refetch is needed
});

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,
  }
)