Reputation: 3448
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");
Upvotes: 29
Views: 69105
Reputation: 341
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.
Upvotes: 34
Reputation: 41
Passing criteria value to useQuery key will trigger function execution when the value changes, also don't forget to pass the criteria to the fetcher for the param to work with the key
const FetchPosts = async (criteria) => {
const {
data: { posts },
} = await axios.get(`${process.env.API_URL}/api/posts`, {
params: {
filter: criteria,
},
});
return posts;
};
const [criteria, setCriteria] = useState('');
useQuery(['posts', criteria], () => FetchPosts(criteria));
Upvotes: 4
Reputation: 2421
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>
Upvotes: 69