Hacker News new | ask | show | jobs
by krishanath 2841 days ago
What is it about React, that needs you to use a state management library? I have programmed in Servlets, JSP Model 2, ASP.NET, iOS, Android, Windows. None of these require a state management library. But React developers seem to think a state management library is a must-have. Is this a cultural thing? Is it due to some limitation of React?
4 comments

You absolutely do not need to use a state management library to build a React app, and, in fact, you need them even less now than you did a couple years back, because the Context API got so much better.

For a lot of straightforward React applications, state management libraries probably make things worse.

"I have programmed in Servlets, JSP Model 2, ASP.NET, iOS, Android, Windows". I suspect in those kind of applications your state management library is just your database. In lack of a database and having the need of reacting on data changes, single-page applications typically resort to some kind of state management library.

In fact, with the Meteor framework state management largely revolves around a client-side reactive mongo API on top of your data, which IMO gives me the best developer experience.

The main issue is that React needs state passed around as props otherwise, which becomes unweieldy if you didn’t have a global state.

I believe it also makes debugging state issues easier if you have a single source of truth.

Edit: this is somewhat alleviated by the introduction of the React Context API[1], which provides some cleaner functionality but requires quite a few extra components in the render tree.

[1]: https://reactjs.org/docs/context.html

>> state passed around as props

Context provides a way to pass data through the component tree without having to pass props down manually at every level. https://reactjs.org/docs/context.html

>> single source of truth

Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. https://reactjs.org/docs/lifting-state-up.html

Note that Context is a pretty new API (1), way newer than most state management libraries. Before that it quickly became unmanageable to lift state up and pass props down all the way.

[1] https://github.com/facebook/react/blob/master/CHANGELOG.md#1...

I guess then I have no idea why Redux is so widely used, given now the Context API exists.
Multiple reasons.

First, Redux has been around since 2015 (and won the "Flux Wars" that had been going on for a year before that), whereas the new `createContext` API only came out a few months ago.

Second, Redux provides a lot more guidance around how you're supposed to structure your application. Context only provides a method for making values available to deeply nested components in the tree.

Third, the Redux ecosystem is huge, with addons available for effectively any use case you can think of. [0]

Please see my post "Redux - Not Dead Yet!" [1] and Dave Ceddia's post "Redux vs the React Context API" [2] for more details on how they relate.

[0] https://blog.isquaredsoftware.com/2017/09/presentation-might...

[1] https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet...

[2] https://daveceddia.com/context-api-vs-redux/

Redux is overused, because of a meme that suggests that the de facto standard React "stack" is React, Redux, and React-Router. That's just a meme (Dan Abramov even wrote a blog post debunking it!) but some memes are hard to fight.
Redux the library is not "state management for react". It's more of a concept that gives you a predictable structure around how state changes over time.

I think what you're thinking of is specifically the `react-redux` library which gave a nice abstraction to the old & clunky React context API. The new context API was released with React 16.3 (which came out March of this year).

The new Context API can't be used in lifecycle methods, which is a bit of a letdown.
the new Context API replaces the `connect()`/`<Provider />` functionality, but not the flux data flow model. Nor does it provide a replacement for the surrounding redux ecosystem - so there's still plenty of benefit to using redux.
> I have programmed in Servlets, JSP Model 2, ASP.NET, iOS, Android, Windows. None of these require a state management library.

All of these have State Management involved somewhere, you might not "obviously" have a "State Management Library" because your stack might encode it simply as "best practices" or it might be a low level detail in the stack that you treat as a simple, black box, but more often than not in many of those environments you are building ad hoc state management libraries all over the place, each application its own little snowflake of state management.

As someone else pointed out, you might be strongly relying on a database or an ORM as your primary state management library. Most React projects are using In Memory data structures, for a vast majority of their work, and most state management libraries you can think of as simply an "ORM-like" thing for managing CRUD in memory.

But we can push the abstraction further. The ORM is often used to build the "M" in an MVC pattern. There are all sorts of complicated Model patterns in various MVC frameworks. Some have more boilerplate than others, some have complex engines and libraries that do a lot of management work. A lot of models use "plain old class objects" (POCOs) of one sort or another, but then have all sorts of ravioli code inside those classes to maintain that the state follows business logic rules, and notifies other classes of necessary changes, etc. That of course depends somewhat on the separation of concerns between your Models and Controllers. (I've seen a lot of "MVC frameworks" and "MVC apps", and almost no two are alike in their M/C separation choices, or their overall state management architecture.)

React itself solely concerns itself with View as a framework; it leaves Models/Controllers entirely to the user. Various React state management libraries are different variations on Model/Controller logic/preferences.

(Some React state management libraries more explicitly define the Model/Controller separation and powers than just about any MVC framework for the platforms listed above.)

As you get into more recent, more "reactive", patterns you see a lot of movement toward "MVVM" Model-View-ViewModel. In those patterns Views and ViewModels are a bit more tightly coupled than MVC. Often a VM has a way to signal data changes (for "two-way" binding) to the View so it can update just the things that changed. In .NET the pattern is called INotifyPropertyChanged. Most other JS frameworks right now (Angular, Vue, Aurelia) follow similar patterns to MVVM, somewhat tightly coupling Views to ViewModels in a similar way to MVVM, even if the frameworks often obscure those details in proxy/signal "automagic". If you look at MVVM projects you will also find some variety for how data changes are signaled. Even .NET's INotifyPropertyChanged has lead to a variety of different toolkits and MVVM libraries designed to manage it and orchestrate it.

React instead only "allows" one-way data binding in views. So even from an MVVM standpoint as opposed to an MVC standpoint, this leaves React state management libraries with obvious goals to do some of the INotifyPropertyChanged-type actions of knowing which state changes at a time, giving React a leg-up in its "one-way" data binding to better know when to re-render components based on state changes. (In many cases a benefit here is that most React state management libraries don't necessarily return to tightly-coupling Views and ViewModel equivalents, most of them look more like MVC than MVVM, despite something of a closer comparison to MVVM in desired outcomes.)

Most of the individual state management concepts in React state management libraries exist in other frameworks, they just often have other names (ORMs, Model Libraries, Controller Patterns, MVVM Frameworks, etc) or are even considered as "user" parts of the stack, left to the individual project to build ad hoc as needed.

Part of what React's state management diaspora has been good for is questioning some basic assumptions in MVC and MVVM patterns. One of those assumptions is "mutable state" where you might just directly update POCO objects each time state changes. (Which works, and has been used for a long time, but also has a history of interesting bugs and debugging issues.) The library shown here is interesting because it's one trying to get the programming benefits of immutable state with the "POCO" terseness of mutable state (`draftState.itemList[55].name = 'new name'` instead of something more like `nextState = curState.setIn(['itemList', 55, 'name'], 'new name')`).