Redux effects and friends are simple too but suffer the same issue, they're so functional that they can be hard to reason about. You really need higher level abstractions to hide that stuff or it gets unwieldy fast.
I think it's the typical 80/20 – hard things are easy with React/Redux, easy things are sometimes hard.
After experimenting with React I'm now using angular2 for my project and apart from some bugs that are left I'm quite happy with it. Architecture-wise I put all state (serializable or not) in multiple-independent plain JS service objects which are injected into the view components through ng2 dependency injection. And they expose their state through observables, which together with things like async pipes makes reactivity really easy.
NG2 services are essentially just singletons that can be injected into any component.
You can specify a server as an application wide provider (ie attach during bootstrap) or a component-specific provider.
Once a service is injected into a component all you have to do is set subscribe a variable to the service's observable. It the variable is bound to the view, it should update automatically. Event handling can be setup to update the observable by calling .next().
NG2 uses Rxjs (Reactive Extensions for JS) which is just the observable structures plus a ton of functional extensions (ie equivalent to reducers) that can add all sorts of inline transforms. Ex flatMap, filter, debounce, etc.
The Rxjs observable API is almost identical to promises. Except you call .subscribe() instead of .then() and the subscription can be disposed of at any time (ie promises always run to completion).
Rxjs uses hot and cold observables. For cold, subscriptions each have their own independent state and disposing of the subscription will stop the observer from retrieving further updates. Hot observables publish updates to all observers and keep updating even when there are no subscribers. Basically, cold observables are like 'on demand' viewing whereas hot is like watching a 'live stream'.
It definitely has a learning curve, but the very simple data flow makes it pretty straightforward, once you've learned what each layer does.