This is fine in simple cases but it doesn't scale well.
Often for a single"area" of my application I might have 15 different queries that are all interlinked and need to be invalidated together.
Having to manually invalidate every one of these in every place that updates my data, getting all of the keys correct, making sure I'm passing in the correct parameters every time, etc. It gets messy fast in a larger application.
And then if you add another query later that also needs to be invalidated, you'll be searching all across your codebase trying to find all the other invalidateQueries calls in order to add it. And I 100% guarantee you'll miss one!
Now, in a different part you have this invalidation code:
queryClient.invalidateQueries(["the-key"])
So far so good. Now let's say someone new in your team is working on a change in the first part and has to change the key for whatever reason. Maybe to this:
Now the invalidation would no longer work (well, technically it still does, because it would invalidate all 'the-key' cache entries, but it would no longer be as targeted). The new team member wouldn't know about it and nobody might notice it (well, hopefully you'd have some tests in place to catch it, but well, sometimes tests don't catch everything).
By using a unified "key generator function" as I propose in my article the keys would stay in sync everywhere they were used for a specific query function.
I'm pretty sure the invalidation still works even after adding id dependency no matter how manny deps you add you can always just invalidate them with just the key, I'm pretty sure I have a query in my app
useQuery(["my-key",{id}],()=>doSomething())// invalidate with just key worksqueryClient.invalidateQueries(["my-key"]);
Yes, this works. queryClient.invalidateQueries() would also work. But I'd rather invalidate as little as possible which means I have to be specific with the keys. Also you might want to update the cached data after the mutation (Updates from Mutation Responses) instead of just relying on. In those case you will have to use the exact key.
In the end there are a lot of ways to get to the desired outcome (using prefix matching, using the exact option, using predicate functions...). You'd have to choose the solution that works for you. I usually tend to think of solutions that are easy to follow and prevent as many undesirable side effects as possible by design (i.E. they require lower cognitive work).
This is fine in simple cases but it doesn't scale well.
Often for a single"area" of my application I might have 15 different queries that are all interlinked and need to be invalidated together.
Having to manually invalidate every one of these in every place that updates my data, getting all of the keys correct, making sure I'm passing in the correct parameters every time, etc. It gets messy fast in a larger application.
And then if you add another query later that also needs to be invalidated, you'll be searching all across your codebase trying to find all the other invalidateQueries calls in order to add it. And I 100% guarantee you'll miss one!
Seems to me some organization with context wrappers could help here.
So, let's just assume this (slightly silly) example. In one part of your application you do have this:
Now, in a different part you have this invalidation code:
So far so good. Now let's say someone new in your team is working on a change in the first part and has to change the key for whatever reason. Maybe to this:
Now the invalidation would no longer work (well, technically it still does, because it would invalidate all 'the-key' cache entries, but it would no longer be as targeted). The new team member wouldn't know about it and nobody might notice it (well, hopefully you'd have some tests in place to catch it, but well, sometimes tests don't catch everything).
By using a unified "key generator function" as I propose in my article the keys would stay in sync everywhere they were used for a specific query function.
I'm pretty sure the invalidation still works even after adding
id
dependency no matter how manny deps you add you can always just invalidate them with just the key, I'm pretty sure I have a query in my appYes, this works.
queryClient.invalidateQueries()
would also work. But I'd rather invalidate as little as possible which means I have to be specific with the keys. Also you might want to update the cached data after the mutation (Updates from Mutation Responses) instead of just relying on. In those case you will have to use the exact key.In the end there are a lot of ways to get to the desired outcome (using prefix matching, using the
exact
option, using predicate functions...). You'd have to choose the solution that works for you. I usually tend to think of solutions that are easy to follow and prevent as many undesirable side effects as possible by design (i.E. they require lower cognitive work).I'm sure your use-case requires what you describe, for me creating custom query hooks work fine for now.
It really does
That's 138 unique queries, most of which are used dozens of times across the codebase 😅
From my experience I think you have to explicitly pass
{ exact: false }
to invalidate partial keys. I could be wrong.