3

I am working on a React JS project. I am using React Hooks (functional components) and React query.

I normally run/ execute the query as follow in the functional component.

const ItemList = (props) => {
  let getItemsQuery = useQuery([ 'get-items' ], getItems, {
    retry: false,
    refetchOnWindowFocus: false
  });

  // The rest of the code goes here
}

Basically the query is executed when the component is loaded so that the API call is made too.

Now, I am looking for a way where I can only execute the query when a button is clicked.

return (
   <button onClick={() => {
       //make the call. The value or value might be overridden when the API call is made when the Call 2 button is clicked
    }}>Call 1</button>
   <button onClick={() => {
       //make the call. The value or value might be overridden when the API call is made when the Call 1 button is clicked
    }}>Call 2</button>
)

As you can see in the dummy code above, the comment explains what I want to achieve. How can I do that?

4
  • So when the button is clicked the query is made, does the query stop if the button is clicked again? Commented Nov 10, 2020 at 14:11
  • It will make another request. Commented Nov 10, 2020 at 14:15
  • Does this answer your question? React-Query: How to useQuery when button is clicked Commented Nov 10, 2020 at 14:21
  • But what if I want to pass a different parameter when the button is clicked? Commented Nov 10, 2020 at 14:23

1 Answer 1

7

Pulling from this answer:

import React, { useState } from "react";
import { useQuery } from "react-query";

const App = (props) => {
  const [text, setText] = useState("");

  // use your async request (axios, fetch, etc)
  // useQuery expects a Promise so we can safely use this instead
  const emulateFetch = async (_) => {
    // axios.get (...)
    console.log(`Passing ${text} to fetch`);
    return new Promise((resolve) => {
      resolve([{ data: "ok" }]);
    });
  };

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

  const { isLoading, error, data, refetch } = useQuery(
    ["key", { text }],
    emulateFetch,
    {
      refetchOnWindowFocus: false,
      enabled: false // needed to handle refetchs manually
    }
  );

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <p>Home page</p>
      <input
        type="text"
        value={text}
        onChange={(event) => setText(event.target.value)}
      />
      <button onClick={handleClick}>Click me</button>
      {JSON.stringify(data)}
    </div>
  );
};

export default App;

Working sandbox.

Sign up to request clarification or add additional context in comments.

6 Comments

But what if I want to execute the query again with the different parameter when the button is clicked?
It looks like you can handle this in your query function. Check out this example: codesandbox.io/s/fervent-wiles-tgy5p?file=/src/App.js
This is what I am after. Cheers.
But what I do not want to execute it when the component is loaded and I only when to execute it when the button is clicked?
I updated my example with something that I think does everything you want it to. Check it out: codesandbox.io/s/reactquery-manual-refetch-forked-3tlxj?file=/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.