7

I have a few useQuery() calls in my react component like this:

const {...} = useQuery(["person.getAll", ....
const {...} = useQuery(["person.getCounts", ....

Then later in a click event after some DELETE/POST request is finished I try to invalidate above queries:

queryClient.invalidateQueries("person");

But it does not trigger the re-fetch. I thought it's some state management issues from my part but then I tried invalidating a specific query like

queryClient.invalidateQueries("person.getAll");

and it works fine..

Is partial query key matching not working in react-query ?

1
  • Have you tried invalidateQueries({ queryKey: ['person'] })? Commented Dec 21, 2022 at 14:32

3 Answers 3

12

React-Query invalidation works off based array prefixes, not string prefixes.

Your useQuery calls should look like this:

const {...} = useQuery(["person", "getAll", ....
const {...} = useQuery(["person", "getCounts", ....

And then you invalidateQueries call will work, with a slight change:

queryClient.invalidateQueries({
  queryKey: ["person"]
}); // invalidate all query keys which start with "person"

queryClient.invalidateQueries(["person"]); // this also works

Alternative, if you are locked into your current syntax, you can accomplish the same using a predicate:

queryClient.invalidateQueries({
  predicate: query =>
    query.queryKey[0].startsWith("person"),
})

But this breaks the React-Query convention.

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

3 Comments

Reason for -1? Please let it be pettiness for the bounty lol
Just to clarify, I'm not the one who downvoted your answer.
Someone is giving all answers here -1. Welcome to Earth.
4

If you see the last example in the invalidateQueries docs, it provides an option for maximum granularity

If you find yourself wanting even more granularity, you can pass a predicate function to the invalidateQueries method. This function will receive each Query instance from the query cache and allow you to return true or false for whether you want to invalidate that query:

So, for your scenario the following should work

queryClient.invalidateQueries({
  predicate: query =>
    query.queryKey[0].startsWith('person'),
})

1 Comment

An invaluable feature for edge cases.
2

This is a matter of how you are structuring the queryKey array. The first constant value of your queryKey array is a whole string, based on what you provided the partial matching won't work if you try to invalidate the queries based on just a part of that string. For this to work, you'd need to structure the queryKey array like so:

const {...} = useQuery(["person", "getAll", ....
const {...} = useQuery(["person", "getCounts", ....

Now the invalidation should work as expected because it's matching all queries that start with "person" in their query key:

queryClient.invalidateQueries(["person"]);

Reference of this on the docs

Comments

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.