-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Some thoughts about Redux's UX #2510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Well, but it wasn't, was it? Before, you had to write every little detail by hand. You can still do that - or you save tons of code, but opt into RTKQ.
Well, no. You stored it once. => RTK Query is a cache mechanism. Data is in there for the amount of time RTK Query's features need that data. Then it is removed. That is exactly why you have to save it to the side if you want to have it accessible for a longer amount of time.
We tried. It ends up being a mess of circular dependencies that do not work with TypeScript. Since how things in the ecosystem are moving right now, TypeScript is at the core of almost every serious project, we cannot add a feature that wouldn't work with TypeScript. See #637. Also, even if you could define thunks from a slice, that wouldn't mean that you could define queries and mutations there. You are conflating thunks with queries and mutations, which are an even much more complex thing. Bottom line: It's just bottom line impossible to do any of those things, given the big number of users and use cases the library has. If we were to add functionality like this it would severely limit how RTK & RTKQ could be used. |
There's really like 5 different questions being asked here:
Answering them in order: RTK Query ImplementationRTK Query is built out of all the same tools, techniques, and principles that Redux has always used: thunks for making async requests, dispatching actions based on request success/failure, a reducer that stores the cached data and tracks loading state, and a custom middleware that helps manage cache entry lifetimes. This is all the same kind of code that you normally would have written yourself... except now you don't have to write any of it yourself :) RTK Query Data StorageCache entries are stored in the state slice managed by the cache reducer. This is normally in You could access those with any normal Redux selector or state lookup, like Thinking in RTKQ and Cache Entry ManagementWhen you use RTKQ, you should think differently about how you work with the data. Stop thinking in "actions" and "dispatching" and "managing state". Instead, it's "is this data cached? What parts of the UI need this cached data? What forces the app to re-fetch this data?" When you use the generated hooks, RTKQ automatically tracks how many components need this data. If that number goes to 0, RTKQ will wait a bit, and then remove the data from the cache if there's still no component needing it. On the flip side, you can set up mutations to invalidate tags attached to query endpoints, and running the mutation forces RTKQ to re-fetch the query data. ThunksA basic thunk looks like: function myThunk(id: numberOrWhatever) {
return (dispatch, getState) => {
// _any_ logic you want here
}
} That thunk could be sync or async. It might dispatch actions, read state, or anything else. For data fetching and async requests, Redux has always encouraged a pattern of "dispatch an action before the request, dispatch different actions on success or failure after the request". So, we made With a "basic" thunk, you can put literally any code inside, so there's no helper function we can make for that (and there's no reason to make a helper function). As Lenz said, we've wanted to add a way to define thunks inside of Thunks vs RTKQ Queries/MutationsTechnically, But, a "slice" is a very different thing than an "API definition with endpoints". So, no, we can't add something like Auth TokensI'll admit that I haven't had to deal with these much myself. But in general, it sounds like you've already got a mutation that tells the server you're logged in. The issue is that "mutations" aren't designed to cache data on the client. A mutation is for sending a message to the server. We do keep some data in the Redux store temporarily while the mutation request is in progress, but conceptually "queries" are what you use to cache data. One option would be to have a Assuming you're letting RTKQ handle fetching the token, then you'd access it via a If the token does come back in the mutation response, then sure, listening for it in a slice's Hopefully all this helps clarify things. |
First of all, thanks for such great explanation and examples - your point is very clear. Now I think that RTKQ is perfect for the cases when UI needs some data or update something. It's 99% of the app. But authentication is different. Both query and mutation don't really fit there - mutation should actually change something, and token from query shouldn't be cached. Taking into account everything you said, I see two ways for me:
Anyway, I'm using RTKQ for the rest, it's obvious. |
Hey.
I've been using redux for years, I liked it even when everybody were saying that it's outdated and stuff.
Then the game has changed with RTK query, I tried to use it... Well, it's definitely better in some way, but now it doesn't feel consistent anymore.
I'm working on an app. It requires login to use it, so it's the first thing I implement.
So I need to make a request to the server with user's credentials, and then update the state (set isAuthorized to true), if everything is fine.
Well, okay, for requests RTK query is fine.
I cached token somewhere?.. How do I subscribe to this change? How do I remove it from there?
I don't actually have control over the state. Alright, I can solve it with slice and extra reducer, subscribed for it.
I ended up storing user's token twice in the store. Ouch.
Now, out of sudden, I need to log out. I can't keep the same logic, I don't need a request this time, just change the state.
I created reducer for this, but at this point I got myself lost in this mess. I have logic in few different places, they depend on each other and it's only the auth flow. How do I maintain it in future?
Documentation stays that
Redux Toolkit does not currently provide any special APIs or syntax for writing thunk functions. In particular, they cannot be defined as part of a createSlice() call. You have to write them separate from the reducer logic, exactly the same as with plain Redux code.
But why? Why can't we just have something like this
Maybe I'm missing something, but this would cover all the bases for me. This is the way I worked with Redux before, it was working for any case!
If you know any wrapper or something, that can just aggregate everythng in one place, please let me know.
If you can explain me what I am doing wrong and change the way I think, It's even more appreciated.
Thanks.
The text was updated successfully, but these errors were encountered: