reduxjs / redux

A JS library for predictable global state management
https://redux.js.org
MIT License
60.91k stars 15.27k forks source link

So, Redux is deprecated? #4350

Closed pablobarria closed 2 years ago

pablobarria commented 2 years ago

You are deprecating a core redux feature (createStore) in favor of adding a separate dependency(configureStore from redux tookit).

I'm not sure the needs of people who may not want to adopt all the RTK were considered here. Personally, I may switch, but I still find it a strange, counter productive decision to deprecate core functionality in favor of a supposedly optional toolset.

jmnyarega commented 2 years ago

🤔 I don't see the point in forking redux. I closely followed the discussions on #4325, you can still continue using the createStore function and disable the warnings in your editor. The redux-core library from my understanding is still going maintained.

pablobarria commented 2 years ago

So, I see createStore is never going away, but if I don't want to use it with a warning, I will have to use _legacycreateStore or I will have to opt in to a bunch of stuff I may not want to opt in (thus making the opt part fairly questionable).

All of this in the service of spamming me about a separate tool I may or may not actually want to use? Still a strange, counter productive decision.

jmnyarega commented 2 years ago

I see your point. In that case, I hope you find a solution to this. I prefer RTK because it solves some of the problems I don't want to think about.

phryneas commented 2 years ago

@pablobarria you can also just pin Redux in the version before the deprecation. You don't want anything new, so there is also no reason for you to ever update it.

But seriously: Redux Toolkit has been the official recommendation for all newly written Redux code for three years at this point.

createStore has been superseeded by configureStore, which has a better api and better functionality. Even a legacy codebase that does not use any other feature of Redux will profit from it.

We could as well just merge all of Redux Toolkit into redux, but the number of complaints by people who don't want to engage with something new would probably be even more than it is with this solution. At this point we have to make either decision, so we have made this one.

mariusandra commented 2 years ago

I'm a bit torn by all the latest changes in Redux.

A bit of backstory: I maintain an alternative to Redux Toolkit called Kea. It's a project I started back in 2015, three years before Redux Toolkit came onto the scene. Kea is nowhere near as big as Redux Toolkit, we're talking orders of magnitude of difference:

image

... but it's still a project that uses redux as a peer dependency, and is used by a lot of people I know (and myself daily at work).

Kea has survived throughout the ages, and has adapted every time React has changed. I've always been grateful for the rock solid redux and react-redux (and reselect) packages that I could rely on to power the abstraction.

I'm now working on a v3 rewrite that makes Kea compatible with React 18's concurrent mode. I found that I actually needed to patch something in core Redux to do so: I needed to pause Redux's listeners when Kea's logic is mounting, to avoid React complaining about bad setState calls. Perhaps that's hacky, but it works.

I came to this repo today to enquire if you'd be interested in a PR to add this pausing feature, or in some alternative way to control listeners... and then stumbled upon the discussions in https://github.com/reduxjs/redux/issues/4325 and https://github.com/reduxjs/redux/discussions/4326 regarding createStore. (Kea actually has a createStore API very similar to configureStore)

Reading through this, I echo the concerns/questions of @pablobarria . Both discussions make it feel like any alternative to Redux Toolkit is now officially a persona non-grata.

Just yesterday I "forked" Redux myself, in order to try out if my approach to pausing listeners could work (it did), but now I feel like I should just keep the cloned code, and switch Kea from being a "built on redux" library to a "redux-compatible core" library. I definitely don't want to also depend on redux toolkit (and immer), nor do I prefer inlining the code. I can of course use the legacy_ function, but that also feels dirty, plus who knows what's next to go?

Is forking the official approach you recommend I take?

phryneas commented 2 years ago

@mariusandra I would assume that your "pausing listeners" would probably work nicely using a store enhancer, so on a code level there is probably no reason to fork.

On a philosophical level: Libraries like yours are pretty much the main reason this approach has been taken. Essentially we had two options:

The first approach would mean that every user of kea would automatically get RTK installed. The second approach allows kea and thousands of other packages to just keep existing as they were doing before.

You now essentially have three options:

Honestly, forking doesn't make any sense. As the deprecation message says, createStore is not going to be removed and as a consequence, nothing else will "go away" either. So, everyone who read the message "knows what's next to go": nothing. After all, createStore didn't just disappear either.

As your library is wrapping around createStore, you can choose either of the two other options. Personally, I would just keep using createStore as that is 100% compatible to every Redux version out there and the deprecation warning is a red squiggle on one single line within your library code. No user will ever get to see that and you can just add a

// eslint-disable-next-line I have read and understood the deprecation message, it's all fine

above your one call to createStore.

Hypothetical scenario for authors of similar libraries: If you were using a Redux-enhancing library that would just add reducers/middleware/store enhancers, but leaves the store creation up to the user, the recommendation would stay as it is: your users should use RTKs configureStore instead of createStore and otherwise could just keep using your library. They would probably benefit from that.

mariusandra commented 2 years ago

Indeed, seems like an enhancer like this was all I needed:

export const pauseListenersEnhancer: StoreEnhancer = (createStore) => (reducer, initialState) => {
  const store = createStore(reducer, initialState)
  const storeSubscribe = store.subscribe
  store.subscribe = (observer) => {
    const pausedObserver = () => {
      if (pauseCounter === 0) {
        observer()
      }
    }
    return storeSubscribe(pausedObserver)
  }
  return store
}

Forking was definitely my first choice, and I'm glad I don't have to. Thanks!

(While googling "redux store enhancer", I found some old code in the docs... seems like there's no more enhancer to pass around?)

Continuing the philosophical thought:

Libraries like yours are pretty much the main reason this approach has been taken

If I could pick your brain for a second... As a Redux maintainer, do you think libraries like Kea should distance themselves from "being redux" in one way or another, or embrace it? I've never known how to properly market/position Kea. However it's hard to talk about Kea as an abstraction over Redux, if such things are basically discouraged. "You can use any abstraction as long as it's Redux Toolkit" seems to be the official suggestion. Thus, should Kea and similar libraries be their own things entirely, or do you embrace people building their own abstractions and alternatives to Redux Toolkit?

In any case, I appreciate the work that went into the simple un-deprecation path for library authors, and the commitment to not break a lot of old code. Thanks 🙏

I also wonder, if a rename other than legacy_ would have made the casual users who know what they're doing happier? Something like createStoreAdvanced...?

markerikson commented 2 years ago

Hiya, folks. Been busy with a conference all day, so just now seeing this.

A few different thoughts off the top of my head.

First: as linked above, the whole topic has been discussed endlessly to death over in #4325 , and documented in https://redux.js.org/introduction/why-rtk-is-redux-today . Hopefully I don't have to re-state any of the points I wrote (repeatedly! emphatically!) in that thread :)

As Lenz said: we're not going to actually remove createStore. Even if we end up putting out a v5 major, which semver says would let us make truly breaking changes, I'm not actually going to remove createStore. It will work, in its current form, forever. Guaranteed. It just has the strikethrough saying we don't want people using it directly, and encouraging them to use RTK overall.

Was reading down the thread, saw the first comment about "needing to customize subscriber behavior", immediately thought "that should probably be an enhancer!"... and sure enough, Lenz suggested that :) Nice to hear that works.

Per the docs bit: yeah, I think somehow the third arg (enhancer) got removed at some point? maybe? I've always been slightly hazy on the exact execution sequence there myself :) So likely the example is just stale.

As far as "Redux abstraction libraries" like Kea, Rematch, and Easy-Peasy go:

My own personal feeling has always been that each of those goes too far in the direction of an "abstraction layer", and end up hiding the fact that you're actually using Redux. Note that I am absolutely not saying "that these libraries shouldn't exist!" Rather that as both a maintainer and a user, I personally would not recommend using these libs because of how they abstract things to a degree that I do not personally prefer.

At the same time: as a maintainer, I fully understand that these libs were created for basically the same reasons that I created RTK, and they do each have interesting and unique features and approaches. Additionally, because they are users of the Redux core, it's still my job to enable those libs to keep working, same as I need to support any of our app-level users.

Now, the Redux ecosystem has changed since 2016-17. Rather than having hundreds of random addon libs for generating action creators or whatever, we do now have an official package that solves the usual use cases and makes people's lives easier. (I had many people come up to me at the conference to say specifically how much they love using RTK and how much it has helped them, which helps show it's accomplishing the goals we had in mind when we built it!)

So, in that sense sure, I do want people to use RTK, because A) I created it and helped build it, and B) I do personally think it's the best and "right" way to use Redux.

At the same time: I will not break userland code, and I don't want to actively discourage people from trying out alternate techniques and building their own approaches if that's what you want to do.

So, it's kind of a wishy-washy answer, but that's the balance that I have to strike as a maintainer here :)

markerikson commented 2 years ago

Oh, and responding to @pablobarria up at the top:

  • Doesn't that make the library itself deprecated? (seeing as there's no redux without stores)

In terms of intent? Yes, in the sense that we do not want users relying on the redux core package.

  • And doesn't that make RTK not optional anymore?

In terms of actual code behavior? No. As stated repeatedly, we are not deleting the package, we are not removing APIs, we are not even adding runtime warnings. It's just a visual indication to grab people's attention and make them aware of how we want them to use Redux today.

  • What is the option for people who do not want the opinionated RTK version? Forking redux?

Anyone who truly wants to continue using the redux core package will be able to do so. Quoting the release notes:

If users do not want to see that strikethrough, they have three options:

To repeat: the simplest possible option for you is to literally do nothing different at all, and keep writing your app the exact same way as always! :)

Do I think that's a good idea? No.

But that is 100% a valid decision you can make and it will work fine.

pablobarria commented 2 years ago

Replying to @phryneas first

createStore has been superseeded by configureStore, which has a better api and better functionality. Even a legacy codebase that does not use any other feature of Redux will profit from it.

If configureStore is the superior option, why not simply offer that with Redux? Like, if your reason for deprecating createStore is that configureStore is better, then why not just offer configureStore as a core offering in Redux?

We could as well just merge all of Redux Toolkit into redux, but the number of complaints by people who don't want to engage with something new would probably be even more than it is with this solution. At this point we have to make either decision, so we have made this one.

I don't want to engage with everything that comes with Redux Toolkit, or at least not all at once. It seems to me like you're taking an exaggerated all or nothing position. As I said, if aspects of the toolkit are simply better for all or at least the vast majority of use cases, then why not make those aspects, and only those aspects, part of core redux?

And replying to @markerikson

In terms of intent? Yes, in the sense that we do not want users relying on the redux core package.

So the objective is to deprecate Redux? Why? Why should people not use the core library directly? How does that affect future development? What if I don't want to use all of the tools that come with the toolkit?

Honestly, it seems to me that the both of you put a lot of time and effort, or at least commits, in writing Redux Toolkit, which is great, but really, I think you're over stepping in your goal to make your baby the new standard way of doing things for redux projects.

Maybe I'll love it once I try it, but it still doesn't seem right.

phryneas commented 2 years ago

So the objective is to deprecate Redux? Why?

Because people, especially newcomers, are hurting themselves by using it and there is a better alternative.

Why should people not use the core library directly?

4 times the code, more risk of bugs, high inconsistency over projects.

How does that affect future development?

The Redux core package has not had any addition (apart from error messages to guide users around it's clumsy api) for 5 years or so, it's safe to assume it won't need any major future development. But if there comes up a reason, of course it will be maintained - also because it is the core to Redux Toolkit, which is under active development.

What if I don't want to use all of the tools that come with the toolkit?

It is a "Toolkit". Choose what you need. Apart from one unfortunate polyfill that we will remove with major 2, everything in there tree-shakes and you will only bundle what you use. My suggestion would be to start with configureStore and createSlice as that will cut down on your code massively as well as add extra code safety and improve IDE support if you use a decent IDE with TypeScript support.

pablobarria commented 2 years ago

Because people, especially newcomers, are hurting themselves by using it and there is a better alternative.

We are hurting ourselves by writing more code than you would like us to write, and choosing to write our immutable state explicitly rather than relying on a layer of code to transform mutations behind the scenes.

4 times the code, more risk of bugs, high inconsistency over projects.

What do you mean by "high inconsistency over projects"?

But if there comes up a reason, of course it will be maintained - also because it is the core to Redux Toolkit, which is under active development.

My question was about the negative impact, if any, of continued direct use of createStore by consumers of the library, of having to support direct use of createStore. My question is, basically, why does this need to be deprecated, other than "it is a way of making sure people realize RTK exists and we'd prefer them to use that instead".

It is a "Toolkit". Choose what you need.

I need to not have 12 mb in my node_modules folder when 300 kb do just fine. I need to not have to rely on polyfills.

After reading all your arguments, your reasons for "deprecating" createStore seem to boil down to "we told you there was a better way of writing redux code, but you didn't listen, so we forced you to listen."

phryneas commented 2 years ago

We are hurting ourselves by writing more code than you would like us to write, and choosing to write our immutable state explicitly rather than relying on a layer of code to transform mutations behind the scenes.

You can hurt yourself all you want if you know that there is an option that doesn't require you to. People following outdated udemy/youtube tutorials (and those are dozens to hundreds of users per day) do not have that knowledge and we have no other way of reaching them.

What do you mean by "high inconsistency over projects"?

There are 15000 redux-themed libraries on npm. Onboarding on a project with the job description "Redux" means you have to learn 3 new libraries, no matter how experienced you are - unless they are using RTK, which is a common denominator by now.

I need to not have 12 mb in my node_modules folder when 300 kb do just fine. I need to not have to rely on polyfills.

If the size of your node_modules folder matters for you I have bad news for you: Redux is the least of your concerns.

After reading all your arguments, your reasons for "deprecating" createStore seem to boil down to "we told you there was a better way of writing redux code, but you didn't listen, so we forced you to listen."

No, it boils down to "we tried to tell you, but you were in another room and never got our message, so we made sure you see a small message until you change 5 characters in your code and move on". Some people just like to argue about this for days apparently.

pablobarria commented 2 years ago

I wasn't in another room. I adopted redux 6 years ago and I have revisited the docs in the last 3 years, mostly to deal with TypeScript integration (and also with hooks, but those are strictly speaking a react-redux concern), yet I didn't notice RTK being pushed there, maybe because I never visited "getting started" again as I had already gotten started. I have also been using react for over 6 years and somehow never missed all of that new functionality, which I keep adopting.

phryneas commented 2 years ago

Relevant pages from the docs, just from a quick skim over the navigation:

Style Guide (recommends RTK as the first "strongly recommended" point) Usage With TypeScript (shows RTK setup) TypeScript QuickStart (shows RTK setup) Redux Essentials Tutorial (8 pages RTK) Redux Fundamentals Tutorial (starts with a warning "do not write code like this in production", ends with a chapter on RTK) Redux Toolkit Overview (self-explanatory) Why Redux Toolkit is How To Use Redux Today Ecosystem (could be more prominent here but mentions the listener middleware)

We have one person writing the docs, who also happens to maintain most of the Redux ecosystem. The only thing we can do with "doable" effort to make RTK more apparent is either to delete the rest of the docs or to add a flashing warning sign on every page.

pablobarria commented 2 years ago

or to add a flashing warning sign on every page

you know? that's just crazy enough to work!

Maybe, just don't spam people's code because you want them to use your library instead of Abramov's. I'll be using legacy_createStore for now.

markerikson commented 2 years ago

@pablobarria and that's the whole point.

You've been notified. You are now aware that RTK exists. Mission accomplished.

If you are choosing to stick with the Redux core, you have now made an informed decision.

But for the record: as maintainers of all Redux libraries, it's fully within our right to do whatever we feel is best for our users, and that includes changing APIs, marking them as deprecated, and encouraging users to follow the approaches we have designed to solve their problems. Complaining because we're fulfilling our duties is, frankly, silly :)

Closing and locking, as there's no further beneficial discussion to be had here.