Earlier quoted context omitted.
As a Redux maintainer, I'd be really interested to know what approaches they used, and what sorts of difficulties they had. (I'll throw out my obligatory comment that you are always welcome to use as much or as little abstraction as you want on top of Redux, and there's plenty of options available to trim down "boilerplate" depending on your situation.)
Those libs add some "magic" which is going against the point of Redux (knowing exactly what's going on). Instead of those abstraction libs I like to use the observable pattern with Rx or MobX
For example, we specifically have a "Reducing Boilerplate" docs page [0] that talks about writing reusable logic for reducers and action creators, like "higher order reducers" or a `createReducer()` util that accepts a lookup table of action types to handler functions. There's many existing libs that implement this kind of pattern [1].
Beyond that, there's other libraries that provide a higher level of abstraction, like automatically generating logic to handle common use cases (normalizing data, updating certain fields, etc) [2].
Updating data immutably can become complex [3], so there's a lot of immutable update utility libraries out there [4]. I recommend Immer [5], which lets you write normal mutative code but then applies the updates immutably.
Finally, there's frameworks built on top of Redux, like Kea and Rematch [6].
So, plenty of options available, depending on what you're comfortable with.
[0] https://redux.js.org/recipes/reducing-boilerplate
[1] https://github.com/markerikson/redux-ecosystem-links/blob/ma...
[2] https://github.com/TheComfyChair/redux-scc , https://github.com/Bloomca/redux-tiles
[3] https://redux.js.org/recipes/structuring-reducers/immutable-...
[4] https://github.com/markerikson/redux-ecosystem-links/blob/ma...
[5] https://github.com/mweststrate/immer
[6] https://github.com/keajs/kea , https://github.com/rematch/rematch