T
TanStack14mo ago
foreign-sapphire

Redux-Saga takeLatest equivalent in react-query land

this is a screenshot from redux saga using takeLatest. really good for picking the latest of multiple queries or requests fired rapidly ( think of adding items to a shopping cart). I wanna know if there's something like this if I'm using only react query in my project
No description
7 Replies
useful-bronze
useful-bronze14mo ago
think of adding items to a shopping cart
that kinda ruined everything because adding items to a shopping cart is a mutation and why would you need to do something there? If the user clicks 5 times on "add to cart", they want 5 items in the cart, not just the last one... the screenshot on the other hand shows fetching users, and that's a query, so totally different use-case so depending on what you want to achieve exactly, there are different ways. If this is for e.g. type-ahead search where you only want the result of the last thing when the user stops typing ?
foreign-sapphire
foreign-sapphireOP13mo ago
okay let me be more detailed, adding items to cart is the exact scenario I'm trying to handle, hence why I used the exact example. we add items to a local state, (zustand) and sync with server, then overwrite the local state. with the response from server. what takeLatest lets me do is cancel old mutations when there's a new one and only uphold the latest mutation(think adding multiple items to cart) so only the last mutation with the most updated items in local state being sent over the server I'm trying to know how I'll handle this with react query, if there's an inbuilt methodology that allows that or if there are common workarounds we've tried debouncing in the past as well, worked for a while but introduced it's own bugs as we later found out. not the biggest saga fan as I'm trying to completely wipe them out our code base but haven't found a replacement for this scenario just yet hi @TkDodo 🔮 I hope I did a better job explaining my usecase, let me know what you think now
correct-apricot
correct-apricot13mo ago
You can handle it with AbortSignal and debounce. You need to write a function that will set up AbortSignal and will debounce call to mutation.mutate(). If you stop adding items and the request fired, if you immediately start adding items again AbortSignal will trigger a promise.reject on a previous request.
foreign-sapphire
foreign-sapphireOP13mo ago
@denis.monastyrskyi thanks I'll give this a try
useful-bronze
useful-bronze13mo ago
I think the only reason why you would have to cancel a mutation is because you have an intermediate zustand store. User adds one item to cart, you add to zustand, then sync with server ("add one item"), then user adds another, zustand now has two items in the cart, now you send "add two items", which would result in a total of 3 items added. So you think you want to cancel the first mutation, but what you really want to do is get rid of the middle man (zustand) and just send a mutation to the server with every click the user makes: - user adds one item, you send "add one item" mutation - user clicks again, you send again "add one item" mutation no zustand, no sync, no problems 🤷‍♂️
foreign-sapphire
foreign-sapphireOP13mo ago
@TkDodo 🔮 the problem with this is user can't add multiple items quickly.
useful-bronze
useful-bronze13mo ago
why not?

Did you find this page helpful?