react-query: Refetch Query only if the state variable is changed

Viewed 19193

I have a select option menu. So, When a user selects an option, I want send a GET/ request to the server with that option and recieve the filtered data from server.

This can be achived using useEffect(() => {// send the request}, [criteria])

Because, useEffect ensures that the request will send to server only if the setCriteria is finished.

But, I am using react-query library. so that, it is not allowed to use useQuery inside useEffect.

As A result, the request is send to server before it the setState is completed. So that, server gets the previous selected value, not the currently selected value.

onChange:

<select
  name="filter"
  value={criteria}
  onChange={async (e) => {
    setCriteria(e.target.value);
  }}
>
  <option>Most recent First</option>
  <option>Price: Low to High</option>
  <option>Price: High to Low</option>
</select>;

Fetch posts:

 const FetchPosts = async () => {
    const {
      data: { posts },
    } = await axios.get(`${process.env.API_URL}/api/posts`, {
      params: {
        filter: criteria,
      },
    });

    return posts;
  };

 useQuery("posts", FetchPosts);

 const posts = queryCache.getQueryData("posts");
2 Answers

You can use your criteria as query key. Whenever a query's key changes, the query will automatically update.

const FetchPosts = async ({criteria}) => {
    console.log(criteria) //from useQuery key

    //your get api call here with criteria params

    return posts;
};

const [criteria, setCriteria] = useState("")

const {isLoading, data: post} = useQuery(["posts", criteria], FetchPosts); //include criteria state to query key

console.log(post) 

<select
  name="filter"
  value={criteria}
  onChange={(e) => {
    setCriteria(e.target.value);  // trigger a re-render and cause the useQuery to run the query with the newly selected criteria
  }}
>
  <option>Most recent First</option>
  <option>Price: Low to High</option>
  <option>Price: High to Low</option>
</select>

Question is already answered. Here's my two cents:

Treat useQuery's query keys like a dependency array of useEffect. Whenever the key changes query gets executed.

If you still want to control the firing of queries, you may explore the "enabled" option to the useQuery hook.

Related