For a lot of straightforward React applications, state management libraries probably make things worse.
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.
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, which provides some cleaner functionality but requires quite a few extra components in the render tree.
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
>> 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.
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. 
Please see my post "Redux - Not Dead Yet!"  and Dave Ceddia's post "Redux vs the React Context API"  for more details on how they relate.
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).
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.name = 'new name'` instead of something more like `nextState = curState.setIn(['itemList', 55, 'name'], 'new name')`).
I actually referenced your blog post as a good overview of how to use the bitmask API, so thanks for writing it!
I also filed a React RFC to make the API a bit more flexible by allowing us to pass a `calculateChangedBits` function directly to a `Context.Provider` instance:
Sebastian Markbage replied in that RFC thread, and tbh the discussion seemed a bit odd. It seemed like he was discouraging me from trying to use the bitmask API, or trying to figure out why I might actually want to use it, when it seems like the entire reason it exists is exactly for something like React-Redux to leverage it for performance optimizations.
Instead you have to (sometimes arbitrarily) have a child component which takes in those properties. This child can then reference those properties in it's react lifecycle methods.
Fortunately this is a pretty simple problem to solve, you could introduce a higher order component which takes in your component and selectors much like redux. Infact, it seems the author beat me to it: https://twitter.com/aweary/status/1011478641320980480
In general, immer plugs in nicely to a lot of contexts, such as redux. Here's another example of how it works with tiny-atom: https://qubitproducts.github.io/tiny-atom/using-with-immer (disclaimer: yet another state management lib, which I wrote).
An alternative approach to immer I've been using in production is http://zaphod.surge.sh/, which is more like an immutable lodash.
Does anyone know when these non-redux approaches are going to get something like TT debugging?
* uses the new React.createContext
* is [highly optimised](https://medium.com/@kidkarolis/tiny-atom-3-0-0-e65a50de7f4a)
* provides `<Provider>`, `<Connect>` and `connect()` for both react and preact
* can be plugged in with immer
* explores how to improve over Redux API by combining dispatching and mutations in actions
* is small