-
-
Notifications
You must be signed in to change notification settings - Fork 15.3k
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
Discussion: consider expanding the Redux core #3321
Comments
Personally I think that redux core being the size it is right now is a good thing, so wouldn't recommend moving RSK into core in any form, nor changing the "scope" of the core. If you'd go with the scoped package name, I would see things like:
And then you could also consider moving |
Very quick side tangent: there's still haziness around the Let's leave the scoping/renaming aspect out of this for now. This thread is gonna be bike-sheddy enough without bringing that into it :) Also, to clarify the point of the discussion: I'm particularly interested in what other functionality should be included in the For example, two items off the top of my head that would be reasonable to have built-in:
Both are small, simple, and unlikely to change much going forward. (Actually, looking at |
Ok, if this is more about "what could we add to the core, as option, and not enforced by default", I'd vote for:
I'm not sold on the createAction helper, IMO it obfuscates the mechanizm a bit, and action creators are already simple enough. |
I realize everything I'm saying below has already been said, but I think it's important to summarize why we would do something like this. ProblemsProblem Redux currently solvesRedux at its core (heh) provides a sane way to manage state in (more often than not) React applications. It provides a really great dev experience (once you learn it) that makes your applications very easy to debug. Problems with the way Redux solves them
The current state
The next stateThat brings us to the conversation we're having at the moment. Should we do something like make RSK the core library? I think a big drastic move is the kind of thing that solves the Redux is not shiny problem and is a very fair attempt at solving the learning curve and boilerplate problems constantly discussed. With all of this in mind, these are the types of things I'd think would be interesting moves for a new version of redux. These are in no particular order, and can be considered the ramblings of a lunatic.
|
At the risk of totally running this conversation off the rails, I'll toss out one more maybe-crazy idea: What if we were to rewrite the core lib in TypeScript? edit Hah, I shoulda read @matthew-gerstman 's comment all the way through first :) |
To be fair I buried that in there. |
Another idea in my head. Two hooks we can provide
Also what if the thunk API looked like this
And then when we do the binding we simply bind the first parameter. I've seen a lot of users do dumb things like reverse these two This would alleviate that. |
Let's focus on just the Redux side of things, not React Redux. That's better suited for reduxjs/react-redux#1063 . |
I will try to keep my idea around Redux, because I see also references to React. Premise: for me Redux must stay agnostic as much as possible and it shouldn't contain third party libraries (unless they become built in inside the core lib). I introduced Redux inside a SPA that wasn't react and it worked like a charm. Fast, reliable and neat. Teammates loved the order introduced by redux. Something nice that the core library should provide, are some utilities that are missing at the moment:
When working outside the framework, these utilities become really handy. |
Other than the benefits to
I think bringing redux-think in is a good idea. I'm not sure why people find the existing API confusing and I'm not sure how it could be improved to be less confusing, whilst still being a thunk. Perhaps the solution is not to bring in thunks bit rather something like
+1. As someone using the
I don't think you could (easily) move them out of the core package as a const store = createStore(reducer, initialState, thunk, sagaMiddleware, logger /*, ...*/);
I think this is a great idea. It's probably the biggest reason I've seen people reach out to const listener = ({ getState, dispatch }, action) => {
if (action.type == 'PING') {
dispatch({ type: 'PONG' });
}
};
applyMiddleware(actionListeners(listener /*, listener2, listener3,...,*/)); It's simultaneously thunk and reducer like, so groking it should not be too difficult for redux users. It could even have a Perhaps something like this already exists or this is worth making into a seperate package anyway? My ideas
I'll think some more and see if I come up with anything else. I'm really excited to see what suggestions others have! |
I'd be against; the redux core is self-sufficient and some of the design choices of RSK are just obfuscating things and making things harder to understand/use (
Not sure which part of the API people find confusing: the arguments, or the fact that you have to return a function? As for replacing it with
Yeah, that would benefit the developers, not the community. I'm for it, but might need to consider this could possibly affect contributors.
Is there any prior art for this? What API do you see? Something like |
I don't want to derail the conversation too much with detail as they can be worked out later once we decide what we want to include, if anything, but you asked, so... Shameless plug: This is more of less what the core package of It would also benefit proposals like reduxjs/react-redux#1150.
As long as the reducers return objects (which it should be to support adding a new key anyway), there's actually no reason you need to define the Either defining the
TBH, me too. I'm more than comfortable with the thunk API and think you couldn't get a simpler async/side-effect model. I made an assumption from my own very limited experience that most devs are pretty comfortable with promises these days and most uses of thunks use promises internally anyway (i.e. AJAX requests). I guess I missed the mark a bit on that one. |
redux-starter-kitRSK is still far from feature complete and, while it is already a step up, it still has basic issues which have been discussed but are hard to find a solution for. Merging it into core makes more sense for functionality that will be used for a majority of implementations. Keeping redux framework/usage agnostic is pretty high up on the list imho. ImmerWill it ship with Immer, even though the majority is not using it? redux-thunkWhile it is good for a large amount of usage-cases, it's also very limited in its use and most projects i see it is not used. If it will be merged, why not provide it by default from the store ? The size-impact is minimal. Adding helper/utility functionsProviding helper functions, like
They all make sense since they greatly remove boilerplate, increase readability and provide basic functionality without being opinionated.
|
Having it active by default would be a breaking change for the API, and mgiht break some assumptions the user already have (maybe there's a middleware thats already using functions as actions for different reasons; it would also make it harder to teach IMO). Would also be against immer; the docs could talk about it in greater details, in section that would also talk about performance improvements toolset, like reselect. |
I'm of the opinion that the core should be as minimal as possible. Move out things like I really don't care if Redux has enough "shiny" features. That's not the point. It's a design pattern codified as a library folks can rally around. I would be happy if there was never another release of Redux, as it's very hard to be improved upon without essentially becoming a different library. I think RSK should stay its own thing. I'm pretty firm on that too. It forms opinions around the library, but there are plenty of other approaches that are equally as valid for certain use cases. We don't need those opinions leaking into the core, making it harder or less clear for how other structure choices can make use of the library. |
@timdorr we could leave redux-core really light and do something like As another note I wanna zero in on the rewriting redux into Typescript. If we were to do that it would give our users a couple of advantages that are worth mentioning.
|
That's what redux-starter-kit is to me. We've already got it, just with a different name. I'm not sure about rewriting Redux in TS. The typings we have already are pretty sufficient and very well-tested. Just because we don't "use" them doesn't mean they're not trustworthy. Also, this puts users of other type systems out in the cold. I'd rather maintain a "least common denominator" of plain JS. It's more readable for the vast majority of our users. I'm not following the argument on source map support. That's already built-in, depending on what package file you pull from. If that's a module (most common for bundler setups nowadays), the source of that file is pretty readable. Just some minor changes by Babel with intact import/exports and comments. |
I think this would be a very good idea, and I would be willing to help do it. It would go a long way to improving the types, IMO. However, you might find you end up changing the API somewhat when doing this, as designing with types in mind from the start would probably lead you towards making some different design decisions.
Agree! Personally, I think there is too much |
I agree with this. Not everyone wants to use Immer... I understand that it's convenient for people who prefer to work with an imperative/mutative API, but not everyone wants that.
Also, agree with this. Especially about FWIW, just be aware that |
Rewriting Redux is in a typed language could prove valuable in influencing a different design or API. My experience with Redux and its typings aren't necessarily a bad one--I've found Redux's third-party typings to be sufficient enough in expressing what it does. The main issue I've encountered is the type boundary across
interface AppDispatch {
<R>(action: AppThunk<R>): R
<T, U>(action: ApiClientAction<T, U>): Promise<
{ payload: T } | PackError<ApiFetchError>
>
<T extends Action>(action: T): T
}
const someCreator = makeActionCreator('MY_ACTION')((arg: string) => ({
type: 'MY_ACTION',
payload: arg,
})
// .. in the reducer ..
if (isSomeAction(action, someCreator)) {
// .. here typescript can infer the correct type for `action`
} I wrote about this kind of approach here: https://medium.com/@danschuman/redux-guards-for-typescript-1b2dc2ed4790 If Redux were to be written with types as first-class, we could possibly avoid some of these hoops? |
One more thing... While we're on the subject of more radical changes, rewriting in TypeScript, etc., I would love to see this API made available in vanilla Redux:
Also, found in And in https://github.com/lumihq/purescript-react-basic/blob/master/src/React/Basic.purs#L165-L169 As @quicksnap mentions above, although the overwritable/overloadable However, at this point, obviously there are way too many really popular middleware libraries out there to just abandon that design, but maybe a new set of It could be as simple as exporting separate "dispatch"/"update" variations which have their own type signatures & can't be modified by middleware, but the See my comment here in an open issue for the It, of course, isn't as powerful of an API as what those middleware offer, but it does give you the capability to fire off (potentially async) effects through Redux while keeping your reducers totally pure. This would add a lot of flexibility to Redux. I've implemented this before on my own using the class API + the newer Context API + setState (wrapping |
I think that including I know there are a lot of options with async, and I think part of the reason that there are so many is that, for most cases, the choice of pattern doesn't matter a great deal. In any case, it's clear to me that we should let problems drive our solutions, and asynchronous effects are always part of the web dev "problem." (While I'm on the topic: nothing is free, and extensibility is a trade-off. e.g. React doesn't provide redux-style state management. Pro: you can use whatever you want. Con: for something like redux to work, it needs something like Anyway, micropackages aren't, in my mind, a goal in their own right. Along those lines, I have no problem with the current inclusion of ...since you asked ;) |
Wow. How is this thread even still open? Clearly I haven't been paying any attention to issues in the Redux core repo :) At this point we're obviously not going to add anything else to the core, but I'm open to adding some more pieces to Redux Starter Kit. |
Note: This idea is almost entirely hypothetical, but it's been suggested a few times and is worth discussing.
The Redux core has been tiny since the beginning. The original intent was always to keep the core small, make the API extensible, grow an ecosystem, and maybe "bless" some plugins along the way. (References: The Tao of Redux, Part 1: Implementation and Intent, You Might Need Redux (And Its Ecosystem))
This has worked great, in the sense that there is indeed a huge ecosystem of addons for just about any use case you can think of. As part of that, the core library package has stayed basically unchanged for the last three years, and the docs have been very unopinionated (usually just listing some available options, like folder structure approaches).
We've recently introduced our new
redux-starter-kit
package. It adds some deliberately opinionated utilities around the Redux core, like simplified store setup with the most commonly used options and some sanity checks, simplified reducers with lookup-table definitions and Immer-powered "mutative" immutable updates, and even creating entire "slices" of state at once. While it hasn't gotten widespread usage yet, the reactions I've seen have been almost universally positive.As part of that, some people have suggested that we might want to consider actually renaming the current
redux
package to something like@reduxjs/core
, and renameredux-starter-kit
to be the newredux
package. I recently ran a Twitter poll asking about this, and the results were a bit surprising. 54% of actual respondents were in favor of this idea.I'll be honest and say that this is not very likely to happen. But, it's worth opening up a discussion about what actual additional functionality is worth adding to the core, if any.
So... thoughts? Ideas? Suggestions?
As a reference, I'll link issue #2295: Request for Discussion: Redux "boilerplate", learning curve, abstraction, and opinionatedness. That overly-long thread does give some indications as to the kinds of things people might find useful.
Tagging @modernserf and @matthew-gerstman , since I know they have opinions on this, and of course @timdorr , @gaearon , and @acdlite .
The text was updated successfully, but these errors were encountered: