Handling rerendering and useMutation
Hi all, currently when wanting to force a rerender on a mutation I move the mutation up in state and pass it as a callback down to the component that needs to trigger it. This often results in prop drilling and coupled state. What is a better approach?
Simplified example:
The
useAddMessage
hook inserts the message into the cache of an InfiniteQuery
using setQueryData
Using version 4.24.6
12 Replies
other-emeraldOP•2y ago
In the example above its not that bad, but I do run into situations as my app grows where it gets out of hand
xenophobic-harlequin•2y ago
Hello
I don't get it. Do you want to rerender ChatInput after addMessage mutation?
other-emeraldOP•2y ago
No the ChatMessages, so that it renders the message that was added to the cache 🙂
AFAIK and experience, a mutation function only rerenders the component the hook is called from
And thus its children
xenophobic-harlequin•2y ago
Can you show ChatMessages internals?
other-emeraldOP•2y ago
Basically it does something like this:
Then flatMaps
messages
and render it.
Where useMessages
looks like this:
Please keep in mind the chat example is just an example (although it exists)
The question is more: How do I ensure a component using a certain cache rerenders when I setQueryData
in a useMutation
from another component that is not one of its parentsxenophobic-harlequin•2y ago
You may use
queryClient.invalidateQuery()
function to invalidate the key of another query. Here's an example
other-emeraldOP•2y ago
But I don't want to invalidateQueries, I want to setQueryData to directly update based on the backend response:)
xenophobic-harlequin•2y ago
Then you need somehow get chatUuid in your mutation so that you can access
["chatMessages", chatUuid]
Here's an example of an optimistic update that uses setQueryData. You may use it as an example, but the idea of manually updating infiniteQuery after mutation is not the best.
Keep in mind that you need to manually manage all the edge cases, like when you are on the last page, or there's only 1 page and your message is added to the 2 page. You will need to recreate all the pagination logic on FE in order to keep it in sync with your BE
That's why invalidation is preferable in most of the cases.other-emeraldOP•2y ago
We are already doing this and managing the edge cases, I feel like you don't understand my question.
I know how to mutate the data, the question is if there is a better way to handle rerendering of components using this cache then moving the call to the mutation function up the component tree
@TkDodo 🔮 could you maybe give your take?
xenophobic-harlequin•2y ago
I'm sorry, I really don't understand why you use mutation to force your component to rerender. It feels like weird and unpredictable behavior. Maybe @TkDodo 🔮 will help you with this 🙂
other-emeraldOP•2y ago
I dont use it to force a rerender, I use it to do a mutation on the server data and then also update the cache directly. However it does not rerender other components using the same query.
To work around this I usually just move the mutation up in the component tree, as it does rerender the component its called from.
Well I guess I understand why we did not understand each other
The issue I'm describing does not really exist
It was just an immutability issue, related to the fact that an infinite query ofcourse has pages and pageParams which need to be deeply cloned 🤡
which apprently I have been doing wrong for like 1,5 years now
thx for the help regardless!!
xenophobic-harlequin•2y ago
It happens 🙂
np mate