
Redux – Not Dead Yet - fagnerbrack
http://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/
======
k__
Redux and MobX are overkill.

What most people want is an easy way to pass down state to nested components,
but the context API is a bit verbose and otherwise you end up with the props-
drilling problem, passing and passing and passing.

Problem is, Redux and MobX solve far more than this problem and in the end you
are stuck with all the complexity they add, even if you don't need the other
benefits they bring.

In 80% of all apps you don't need much state. They don't have deeply nested
components so you can simply store the state in your root components
(Screen/Page) via setState and pass everything down via props.

If you end up with deeply nested probs, use "unstated", it adds a bit better
usability to the context API and lets you avoid the props-drilling problem.
You basically get something like the "connect" from Redux, without the rest
Redux would require.

If you somehow end up with an app that fits in the 1% who need fully
predictable control over their global state, go for Redux.

React is the simplest framework I've ever seen, sadly Redux and co made it
much more complex than needed to be, which drove many people away from it.

~~~
mettamage
It seems interesting. I have one code reading issue, could anyone be so kind
to explain it?

I read things like: <Subscribe to={[CounterContainer]}>

Why are [ ] needed? And what do [ ] mean here? I thought { } were enough for
evaluating code.

~~~
mettamage
Ah, right! It just evaluates to JS, fair enough. Thank you all!

~~~
eyelidlessness
Almost. It evaluates JS _expressions_ (not statements). It's a minor
distinction but trips a lot of people up.

------
ralusek
I've been using mobx-state-tree for the latest couple of projects after Redux.
I like them both, but I prefer mobx-state-tree for a handful of reasons.

1.) There is an immutable data store with action-driven changelog, just like
Redux.

2.) The immutability of the data store is baked in and enforced. The necessity
to provide changes to the data store within an action is baked in and
enforced.

3.) Having actions baked in as methods rather than having to create "action
creators which in turn dispatch actions" is a nice reduction in boilerplate.

4.) Being able to add action listeners AND state listeners are baked in, and
can be done at any level of the state's depth. To watch state changes in
redux, for global changes not related to a particular component, I had to
write: [https://github.com/ralusek/redux-store-
watch](https://github.com/ralusek/redux-store-watch)

5.) Mobx's observers on react render methods makes the renders far more
efficient than what could be achieved with react-redux easily, without really
ensuring that the props being passed in are as granular as necessary or
shouldComponentUpdate is correctly identifying state changes. In mobx, the
most granular access of the lowest level state can be detected within a render
method, and only when that very specific value is replaced is the component
rendered.

6.) Computed values on mobx-state-tree are baked in without the need for
something like reselect

I like Redux, I enjoy working on projects that use it, but I think that I
think I'd have to admit that I prefer mobx-state-tree.

~~~
johnwheeler
React ecosystem noob here. To point #5, I remember reading that MST has some
overhead over Mobx, does it come into play with these renders?

~~~
AWebOfBrown
Performance was my main concern with MST, most notably if your data modelling
involves A LOT of entities, things can get slow:
[https://github.com/mobxjs/mobx-state-
tree/issues/440](https://github.com/mobxjs/mobx-state-tree/issues/440).
Binding methods on every instance of an object is a lot of overhead.

I really liked using MST when I spent a few days fiddling with it. However, I
really don't want to get trapped with perf bottlenecks I can't easily fix.
Whether I'd actually run into trouble - I have no idea, but vanilla MobX is
excellent enough that I'm happy sticking with it. I'd love to use MST more
though.

------
coding123
Was on a team at a large company - and the architects had a decree that
everyone must use React - good decision. Except one problem was that everyone
was just using Redux like it was part of React or something. I don't know how
many components that had to maintain their own state got stuck in Redux
nightmare land where special keys were being used to keep each component
separate - it was a complicated mess inside the react component. This
component didn't map to a single concept of state, instead many "copies" and
different versions of that copy could be on the screen at once - and no one
really "got it" that they were feeding really deep into a major anti-pattern.

I kept pointing out to members of the team that even Dan Abramov's post about
maybe not needing Redux... but it fell on def ears like I didn't "GET" redux.

I totally understand the enticing time-travel feature, but I think too many
people jumped on the ship before it was ready for the use-cases different
folks had in mind.

~~~
lobster_johnson
This type of data flow where components need to plug into multiple _instances_
of the same type of state is an area where Redux doesn't help you, and
solutions tend to be ad-hoc, using things like the "special keys" you mention.

A challenge I had recently was a location form field, where the user is
offered autocompletions as they type. The autocompletion state is specific to
the component; every field needs its own unique state. So to represent this
with Redux, the component has to generate a "state ID" (basically just "new
Object()", as I recall) that serves a unique identifier that it can request
lookups under. The autocomplete() action then has to take a state ID as a
parameter, and associate all lookup state with that ID. Internally, I
implemented this as a layer on top of the autocomplete engine, so that the
underlying layer didn't know about the ID. Even so, it wasn't beautiful. And
of course it was susceptible to leaks -- it was necessary to "unregister" the
state ID on unmount. It was unpleasant enough that I considered not using
Redux, but I've done that before, and I really wanted the whole state
transition machinery.

Has anyone created a solution for this, I wonder? It's possible that a new
Redux store per field would have solved everything. But can you connect a
component to multiple stores? Some components need to have instance data _and_
access the global store (e.g. current logged in user).

~~~
acemarke
Yes, there's been quite a few libs already created to try to implement per-
component-state tracking in Redux:

[https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/component-state.md)

That said, did the component really _need_ the autocomplete state to be stored
in Redux in the first place?

~~~
lobster_johnson
Thanks for the link. Well, _all_ state transition mechanics benefit from the
strict, pure serializability that Redux offers.

In this case, it was a component that not only autocompletes a location, but
also offered to geolocate the user (via the browser's geolocation API) and
supported a few other features that meant it was several competing concerns
wrapped into a single UI. Those can get hairy if you don't do a Redux-type
state machine.

~~~
baddox
I’m curious what the shape of your redux state tree and component tree looked
like. It sounds like you had a collection of n components, each with its own
autocomplete component. Was there not an obvious parallel in the redux state
tree for each of these n components?

Also, as a side note, you may want to check out recompose’s withReducer HOC,
which is effectively a way to use the Redux action+reducer flow to manage the
state of a single component (without the separate store, the context stuff,
etc. that Redux provides):

[https://github.com/acdlite/recompose/blob/master/docs/API.md...](https://github.com/acdlite/recompose/blob/master/docs/API.md#withreducer)

In case you’re interested, ReasonReact also provides a reducer component as
the only way to have a stateful component. The pain of “boilerplate” basically
goes away in a typed language:

[https://github.com/reasonml/reason-
react/blob/master/docs/st...](https://github.com/reasonml/reason-
react/blob/master/docs/state-actions-reducer.md)

------
elliotlarson
I've built a couple of applications with React. I've spent the last 6 weeks on
a contract where I'm building a React based Google maps widget. I'm getting to
the point where I'd like to break up a large "smart" component into smaller,
more maintainable smart components. So, I'm looking for a state management
library to help. I've walked through some training courses at Udemy on Redux
and I've built a small personal project with it. I don't want to beat a dead
horse, but the boilerplate is really off putting. I feel like I'm being
exposed to the internals of a framework that's missing some higher level API
abstraction that makes state management less onerous. I think the Rematch
library presents a nicer surface API:
[https://github.com/rematch/rematch](https://github.com/rematch/rematch). But,
I'm hesitant to use it over Redux for client work because I want to make sure
I develop something that's easy to hand off, and Redux is sort of king right
now. I just spent some time with the apollo-link-state docs. I know it's
young, but this does not look like an improvement over the Redux state
management API. Hopefully if this is to be the Redux successor, the API will
improve with maturity. I kind of wish Ember Data was usable as a standalone
library. It looks like such a nice, easy to use wrapper around state and data
management.

~~~
chrisco255
MobX might be a good option for you. But to your point about Redux's boiler
plate, it may be off putting and somewhat onerous, but like brushing your
teeth...putting up with Redux's boilerplate will pay dividends over the long
run. I think that Redux changes your program's architecture in a powerful way
in that your UI becomes fully driven by deterministic state changes. There's
no way around this but to explicitly declare all the possible actions your
users and processes can take and expressing the mutations in state those
actions should result in through reducers. Trust me that for any non-trivial
and long-lived application this pays dividends in the long run. Simpler state
models with less boilerplate tend to be great for small-medium projects that
are short-lived, but do not evolve well.

~~~
elliotlarson
Thanks for the reply. MobX does look interesting. I recently watched Preethi
Kasireddy's presentation comparing MobX and Redux
([https://www.youtube.com/watch?v=76FRrbY18Bs](https://www.youtube.com/watch?v=76FRrbY18Bs)),
which I'd recommend watching to anyone in my shoes. A couple of things give me
pause about MobX. One, it doesn't quite have the inertia or industry buy-in
that Redux has. It's popular, but in terms of GitHub stars, it's less than
half as popular as Redux. Alone this isn't super meaningful, but if you look
at the contributors page for MobX, it seems like it's predominantly the work
of one person. Again, not super meaningful on it's own, but Redux seems to
have the benefit of a larger group of core contributors working on it and
larger community support. Just circumstantial evidence, but I feel like it's a
safer bet for client work on this front. There's value in following the well
worn path. The other thing that gives me pause about MobX is this opinion I've
heard a few times and you've just re-iterated, which is that MobX is easier to
work with and possibly better for smaller projects, but Redux scales better.
I'll concede, it's possible I need to quit whining about the funkiness of
Redux and live with it for awhile. It might grow on me. :)

~~~
AWebOfBrown
You might want to fish up the MobX users list in one of its github issues. The
users list is huge, and includes rather large projects such as Battlefield 1's
UI, CoinBase and I think the new MS Outlook to name just a few.

------
acemarke
Oh hey, that's my post.

So, uh... Redux co-maintainer and author of that post here. Happy to answer
questions and point people at possible solutions :)

~~~
daveidol
Thanks for doing what you do.

I contributed some of the initial documentation [1] for testing middleware
back in the day.

Wondering if there are any areas in particular you'd be looking for
contributions? I use redux every day and would like to contribute back some
(if it would be helpful).

[1]
[https://github.com/reactjs/redux/pull/559](https://github.com/reactjs/redux/pull/559)

~~~
acemarke
Yes, absolutely! I have a _ton_ of additional docs improvements I'd like to
see. Most of those are currently listed as open issues with a "docs" tag [0],
and I've got some other docs ideas floating around in my head besides those
(like completely revamping our docs around React-Redux).

Beyond that... oh, boy. I'd love help maintaining my React/Redux links list
[1]. I've been really busy the last few months and have fallen behind on
adding new links, and it could also use some maintenance attention to look at
the existing links and figure out which ones are outdated and not really
useful any more.

The "starter kit" lib I threw together [2] could use more design work and
ideas to figure out what other "batteries included" type things we would want
to include out of the box as an official Redux-branded library to solve some
of people's common pain points.

React-Redux has some open PRs related to React 16.3 [3]. It's starting to look
like we need to put together a bigger v6.0 major version release with some
combined changes, and it would be good to get more eyes on the situation to
figure out what's needed. There's also an open PR for adding an "object
shorthand" for selectors with `mapState` that's been lying around for a while
waiting for someone to add some tests so that we can say we're happy with how
it works and merge it.

[0]
[https://github.com/reactjs/redux/issues?q=is%3Aissue+is%3Aop...](https://github.com/reactjs/redux/issues?q=is%3Aissue+is%3Aopen+label%3Adocs+sort%3Aupdated-
desc)

[1] [https://github.com/markerikson/react-redux-
links](https://github.com/markerikson/react-redux-links)

[2] [https://github.com/markerikson/redux-starter-
kit](https://github.com/markerikson/redux-starter-kit)

[3] [https://github.com/reactjs/react-
redux/pulls?q=is%3Apr+is%3A...](https://github.com/reactjs/react-
redux/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc)

~~~
daveidol
Awesome! I'll absolutely spend some time going through this and see what I can
do to help out - thanks!

------
bnchrch
Redux is far from dead but I do think apollo-link-state has the ability to
take its crown if GraphQL continues to gain wide adoption; which I believe it
will.

Though it's a very new library (Dec 2017) so it has a long way to catch up in
terms of tooling and support.

I just happened to write an article on apollo-link-state for those who are
curious about how it's used.

[https://hackernoon.com/setting-up-apollo-link-state-for-
mult...](https://hackernoon.com/setting-up-apollo-link-state-for-multiple-
stores-4cf54fdb1e00)

~~~
acemarke
So I haven't actually used GraphQL at all, although I've sat through a bunch
of talks on it and am pretty familiar with the concepts. That said, I have to
say that the examples I'm seeing for setting up link-state mutations don't
look like they're particularly concise.

Given that "boilerplate" is a typical complaint about Redux (which can itself
be handled with whatever abstractions you want to put in place), I'm not
seeing the appeal here. Is it just a case of "we're already using GraphQL, so
GraphQL all the things" ? (Note that the article itself doesn't use the word
"boilerplate", I'm just pointing at that as a reason I've seen people throw
out for wanting to move to link-state.)

~~~
city41
apollo-link-state would almost certainly be considered a hack if it was made
by anyone else other than the Apollo team. Just the fact you need to manually
specify the __typename field feels wrong to me. But I do have hopes that
Apollo will grow and improve here, and apollo-link-state will likely evolve
into an elegant tool.

~~~
AWebOfBrown
I felt the __typename was really awkward too, but Peggy Rayzis (of the Apollo
team) told me awhile ago that they're working on removing that requirement, if
it hasn't been done already. I don't think it's anywhere near as feature rich
as MobX for local state though, so I use Apollo for remote data and MobX for
local.

------
cmorgan8506
I think redux is a great pattern for state management. With that said, I think
there is still room for improvement.

Like most people have mentioned, it would be nice if we could some how reduce
the amount of boiler plate needed, or perhaps a pattern will emerge that will
help manage it better.

For me, the true benefits of redux became clear when I learned how to properly
normalize the shape of the data ([https://redux.js.org/recipes/structuring-
reducers/normalizin...](https://redux.js.org/recipes/structuring-
reducers/normalizing-state-shape#designing-a-normalized-state)) in the store.
Unfortunately to do this efficiently it requires more boilerplate and
dependencies like normalizr.

At this point in the evolution of SPA architecture, it definitely feels like
something is wrong because of the way we manage our data across the stack. We
normalize our data to our RDS, de-normalize it in our API, then re-normalize
it in our application interface.

Interesting and exciting to watch the evolution take place though.

~~~
acemarke
Hah, I wrote that whole "Structuring Reducers" docs section! Glad it was
beneficial :)

I personally am a fan of Redux-ORM [0] as a tool for handling normalized state
in the store (and I show how to use it in my "Practical Redux" tutorial series
[1]), but there's quite a few other options as well.

My biggest frustration with the word "boilerplate" is that it not only gets
thrown around a lot, it means different things to different people. Which
_specific_ aspects concern you? What pain points have you experienced?

[0] [https://github.com/tommikaikkonen/redux-
orm](https://github.com/tommikaikkonen/redux-orm)

[1] [http://blog.isquaredsoftware.com/series/practical-
redux](http://blog.isquaredsoftware.com/series/practical-redux)

~~~
cmorgan8506
It's well written, so thanks for that. I have a client project coming down the
pipe that will likely include redux, so I'll have to check out Redux-ORM.

I agree that the term boilerplate has been diluted lately. I also have to
admit that I use it in this instance because it seems to have become the
adopted term for what essentially means "takes a lot of code no matter the
complexity". So to clarify, when working with Redux, it _feels_ like it takes
a lot of code to handle data in states, no matter the complexity.

More likely, redux is intended for larger projects with complex state
management. So yeah, there is a lot of code to setup even basic data within a
state, but the benefits probably start paying dividends as the state becomes
more complex. With that said, I doubt anyone working with extremely complex
states is complaining about too much "boilerplate".

I was considering contributing to Redux but when I checked github it didn't
seem like there was too much that needed help. Let me know if that's not the
case. I love the project and would enjoy contributing.

Thanks again for your hard work!

~~~
acemarke
There's a _ton_ I'd love to have help with :) See my comment elsewhere in the
thread:
[https://news.ycombinator.com/item?id=16918991](https://news.ycombinator.com/item?id=16918991)
.

------
hliyan
In 2016, we developed several very large applications using Redux. The
clarity/simplicity gains quickly evaporated as the system grew in size. The
experience led me to develop an alternative [1], which I have shared here
before. We used it for several production components and the productivity and
testability gains were very clear.

[1] [https://hackernoon.com/transmission-tx-a-flux-alternative-
fe...](https://hackernoon.com/transmission-tx-a-flux-alternative-fe0630eed2a3)

~~~
atombender
What you describe in that blog post is essentially classical MVC, as far as I
can see, except you don't use the term "controller" and all state changes are
requested via events instead of being made directly on the data model. But
many MVC systems work like that -- it's not like MVC is standardized.

What this doesn't really get you compared to Redux is a consistent, serially
updated, immutable state tree, and every state ("engine") becomes a somewhat
ad-hoc event manager. Redux does get the concepts right, in my opinion. Your
system doesn't really solve anything better, as far as I can see; it just
calls actions "events" and splits the state tree into "engines".

Redux is too simplistic, though. It does nothing to solve some of the actual
hard problems people face in an MVC system, such as async loading (which comes
with a bunch of can of worms: Retries, error handling, idempotency, progress
events, cancellation, etc.). I don't know of anything that does this well on
top of Redux.

The fact that the event model and state tree are both global and shared means
Redux makes it hard to encapsulate stuff, too. Encapsulation is less of any
issue if there is a single instance of everything; if you have a single user
controlling the page, then it makes sense that there's just one global user,
and one global state for each of the user's things. But often you have
multiple instances of state, and there are no tools to help you coordinate
events and actions. For example, say you have a page that wants to display
several charts in different boxes, and users can add new charts to the page.
Every chart component "points" to which dataset it wants to render, and each
dataset is a separate node in the state tree identified by ID. The actions and
events then all have to refer to this dataset ID; you effectively get a little
"routing layer" for actions where each action needs to look up the state by
dataset ID to get the actual thing to operate on. I've not found any reusable
tools to handle this.

One reason Redux doesn't scale well is just the amount of boilerplate and
repetition. You can solve this with some smart meta programming, especially in
TypeScript. But it's not entirely a solved problem.

~~~
nemothekid
> _Redux is too simplistic, though_

+1. Redux is a great library, but I think its a little hard to grasp at first,
and it doesn't yet provide a proper framework for solving problems in a clear
manner. It wasn't until a year + of using Redux and reading quite a bit code
until I developed a mental framework for how to approach certain components in
Redux (and whether to use Redux at all, vs. setState).

Your "chart grid" example is something that I went through 3 iterations of
until developing the "right" higher order component (which if you squint,
could be confused for meta programming) for our use case. As a developer what
you want is the right abstraction that prevents your "dataset ID" from leaking
everywhere (ideally only your HoC should care about your "dataset ID", much
the "redux-form" API you really don't need to interact with the "form" name
once you've defined it). Once you have that, then you hopefully you have a
reusable API that can scale or at least small enough to live in one
developer's head without them having to wrestle with the entire application.

I'm not sure how you fix it. Most of the patterns I discovered already exist
under many different Medium articles.

~~~
shados
Ironically, it used to be much simpler. The community was very much around
using Redux like you would event sourcing (even though thats not how it was
talked about), and it was much into the FP/Elm-like patterns it provided. You
could go on Discord and chat about a problem you had, and people were actively
trying to solve it.

It didn't take long as Redux got popular for the discussion to turn into "how
to avoid boilerplate", "how to make things more SOLID" (OOP principles in
Redux, lol!), and "you should use setState most of the time".

That was the silent nail in the coffin. Very little progress was made in Redux
patterns ever since that would not better be solved using other tools (MobX,
Apollo, 16.3 context, whatever). Which is a shame: "Old school Redux" is
amazing. There's a reason initially people flocked to it and said "OMG use it
all the time for everything!". It's really that good. "Modern" Redux is a
fragmented overcomplicated useless mess with a community that missed the
point. Now get off my lawn, I guess.

~~~
acemarke
Hiya, Shados. Long time no chat :)

I don't recall ever seeing comments about Redux and "SOLID". The commentary
about "boilerplate" and use of `setState` has been in response to people's
concerns. It's a shame that's where we've had to focus our time and attention
in messaging.

Can you clarify what you mean in the last paragraph? What specific concerns
are you thinking of?

I know you've talked in the past about the way your teams are using Redux. I'd
love to see a couple posts that give some details on that.

You know I'm always happy to chat about ways we can improve the docs and help
the community. _Please_ ping me sometime - I'd love to hear whatever
suggestions you have. You know where to find me :)

~~~
shados
Note that when I say the "community" here, I don't necessarly mean you or
people close to the project, but I rather refer to what I've been seeing here
internally, when talking to people at meetups, twitter, etc.

In the early days, the average Redux user was someone who had been burnt by
Backbone or Angular 1.x state management, was excited about the solution Redux
provided, was curious about Redux's FP characteristic or more rarely might
even have been an FP zealot. There was a lot of chat around that area, how to
handle specific problems from that angle.

As time went on and it became very popular, the "community" (I use the term
loosely, as there's no single entity representing "the community") grew, and
the typical Redux user was very much the same as the average JS dev. Usually a
OO background or familiar with more classical languages and patterns. Just
want to get shit done and doesn't care about the Redux pattern's unique
characteristic. Uses Redux because everyone else is, not because they see
value in the event sourcing-like decoupling.

A lot of things come from that. Like already mentioned, the focus came a lot
more to "how to I reduce boilerplate", "waah I dont like passing props down",
"code reuse!", "how do I make things look like my familiar OOP patterns".

That's all valuable and I don't want to downplay it (there's only so much
nuance I can put in a stack overflow post), but a lot of this is available in
other tools and other frameworks. MobX and state trees are pretty nice. I can
just use that.

Redux itself has a few things others have not:

1- Popularity, but that's a completely artificial thing. Any other pattern
could become popular. It does mean it has the most complete ecosystem, but we
can replicate anything elsewhere if we need to.

2- FP-ish, Elm-esque, event sourcing-like characteristics. Nothing even
remotely mainstream outside of other languages (Elm, PureScript, ReasonML)
have this. But there's very little effort these days in tapping into it.

For example, the "connect all the things everywhere!" makes the predictable
dataflow aspect of Redux a lot more fuzzy. In large apps we don't have much
choice though: there are major perf issues if you don't connect deep enough.
It's a problem that can be solved, but I've never seen it solved. Redux being
used as a glorified context container to save on typing can be solved with
better design patterns. There's very little research done in that area
anymore, so it's here to stay. Side effects being handled by
thunks/epics/sagas works fine, but we could do better. Back then there was a
LOT of research and attempts done in that area (remember redux-loop? I miss
redux-loop. The syntax sucked. Can't we do better, several years later in a
world of generators, async/await and observables? I bet we can!).

The obsession in making Redux, a functional event sourcing like-thing into
something palatable to the average developer is just trying to fit a square
peg in a round hole. There's nothing unique about Redux to make it appeal to
those use cases and sub community. What if we looked at Redux, and instead of
only focusing on that, we pushed what makes it unique to it's limits?

After all, back when the first Redux demo and timetravel debugging was shown,
the world revolved around OOP JavaScript. It pushed people out of their
comfort zone a little.

I'd show you the code we write here, but with hundreds of devs, they learn
from the same place everyone else do. As we've grown, all the patterns (and
anti-patterns) you see everywhere are also present in our own code, and we
fight these battles internally too.

I'd be more than happy to chat more, but to me, that was always a battle that
was lost years ago, when discussions devolved into "ivory tower vs pragmatism"
(remember [http://blog.isquaredsoftware.com/2017/01/idiomatic-redux-
tho...](http://blog.isquaredsoftware.com/2017/01/idiomatic-redux-thoughts-on-
thunks-sagas-abstraction-and-reusability/) ?)

This really isn't a form of discussion I feel is productive. To join force
within a problem space and solve problems in that space, you need several
people aligned on a common goal. The problem space and common goal I'm
interested in isn't "How do we make Redux work for everyone", it's "given an
assumption that certain FP patterns, event sourcing, global state and event
logs are high value patterns, how do we solve real world problem with them".
I'm not sure this is possible anyore without alienating tens of thousands of
frontend developers, without starting something else from scratch.

Edit: phew I hit enter and didn't even realize how much I wrote.

So TL;DR. You and the rest of the team are doing a fine job, but as with all
things that are popular, there are "sub communities", and its impossible to
make everyone happy. My pie in the sky dream is for people that don't like
Redux to use something else, and for Redux to focus on its strength instead of
always trying to fight its (by design) weaknesses.

~~~
acemarke
Hah, that's a lot to digest there :)

I've already spent more time in this thread than I really should have, and I'm
also sorta slightly burnt-out after spending the last few weeks putting
together my first Redux workshop. My immediate priorities for the near future
are trying to consolidate the PRs and issues we have for updating React-Redux
to work with React 16.3+, and pushing forward on the "redux-starter-kit"
package I put together.

That said, yeah, I _hate_ that we've had to spend so much time "defending"
Redux rather than figuring out niftier things to do with it. I've seen a lot
of interesting experiments in the community, but haven't had time to really go
off and investigate or play with them further. (I don't even have enough time
for all the blog posts I want to write :( )

At a minimum, Redux has been hugely instrumental in changing the minimum bar
for debuggability and state tracing, but yes, I'd love to figure out ways to
push the envelope somehow.

~~~
shados
> That said, yeah, I _hate_ that we've had to spend so much time "defending"
> Redux rather than figuring out niftier things to do with it

Yup, everything popular goes through that. I like the MMORPG analogy. New MMO
comes out, is popular, shiny, everyone's into it. Then the WoW communities
move to it and request...DEMAND that it be changed to match their
expectations. Game devs try super hard to catter to the WoW communities and
fail. WoW players all quit. Game developers then either give up, or focus on
the core player base that actually liked the game as designed originally. At
that point the game either thrives and becomes the best it's ever been (with a
much smaller user base), or it dies.

Ember is one of those I think: I don't like it, but everyone who hates Ember
stopped using it long ago, and it's serving people who like it quite well.
It's not shiny or sexy, but for them, it works very well.

------
sktrdie
One major problem we had with Redux, especially in a large organization where
reusability is very important, is that we found it hard to reuse most of the
redux logic (reducers/thunks/selectors). The pure components were easily
shared across different teams, but most of the other stuff was too much redux
or app-specific that we couldn't really reuse it.

We experimented with simply using large stateful react components instead of
redux for certain areas of the app, and our reusability improved dramatically.

Any thoughts on how this is tackled by some hardcore redux users?

~~~
daveidol
Reducer, middleware, and "action creator" factories that take config will
allow for a pretty high level of reusability. We have several internal redux
libraries of generic reducers, middleware, etc. and they all export _factories
that return these things_ instead of naked reducers, middleware, etc.

The factories can take config for which action types to handle, etc.

~~~
bshimmin
This is great progress; given a little more time, I hope we will be able to
recreate the fabled AbstractSingletonProxyFactoryBean!

~~~
daveidol
Yeah, those lucky Java developers get all the best classes

------
daveidol
Personally, I find Redux to be a joy to use and write code with. I agree that
there is a lot of "boilerplate" _for new developers_ , as Redux does not
really come with a batteries-included "framework" to build CRUD apps -- that's
on you to figure out and write.

One you _do_ write this framework in Redux, however, you can reuse it and the
amount of unnecessary boilerplate goes to near zero in my experience.

We just need a de facto open source framework built on top of Redux for people
who haven't worked with it extensively to build with.

~~~
acemarke
I know. I've seen _many_ other higher-level abstractions on top of Redux (per
my comment elsewhere in the thread). A year ago, I opened up an issue [0] to
discuss ways we could improve the "getting started" experience, reduce
boilerplate, add better abstractions on top of the base primitives, etc. The
thread got some decent comments, but nothing really concrete came out of it.

A few months ago I had a little bit of free time, and threw together a tiny
"starter kit" library [1] that is intended to simplify a couple of the common
pain points (basic store config, and writing reducers with immutable updates).
I haven't had time to push it further, but long-term it's likely to become an
official Redux-branded "use this to get started" addon.

I'm very open to further ideas and suggestions around this topic.

[0]
[https://github.com/reactjs/redux/issues/2295](https://github.com/reactjs/redux/issues/2295)

[1] [https://github.com/markerikson/redux-starter-
kit](https://github.com/markerikson/redux-starter-kit)

~~~
daveidol
Cool! I hadn't seen that. I like the idea of a solid starter kit library,
although (from quickly reading the README for your starter kit) I think it
should probably include more: specifically facilities for making HTTP calls,
serializing/deserializing request and response data, caching data and fetch
status for the requests, etc.

From working with people who haven't used Redux before - these seem to be
common things people new to Redux want to do but find difficult to get
started. (The boilerplate around making actions and switch statements, etc.
seems a bit secondary in my opinion)

However, I realize the "proper" way to do the things I listed above is
inherently pretty opinionated, so I totally understand why the Redux library
itself has avoided including these things (it's much more flexible as-is; and
probably why it's been so stable and stood the test of time).

~~~
acemarke
Yeah, that gets _wayyyyy_ past what I want to do.

There are quite a few existing libs for doing data fetching and collection
management ( [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/entity-collection-management.md) ), ranging from simple
normalized reducers to complex "auto fetch from a REST or JSON-API and provide
full CRUD support" libs.

I simply don't understand the complaints about switch statements myself, but
it keeps coming up, so it seemed like a simple enough starting point for a
"starter kit" library like this.

------
ghayes
As an avid Elm user, I am happy to see continued usage of Redux. Redux does a
great job of bringing functional reactive programming to React.

~~~
swyx
functional, yes. Reactive? no.

------
chvid
To be honest I always thought Redux to be hard-to-understand, obscure in its
terminology and terrible over-hyped essentially doing something that could be
much better described/modelled as a straight out application of the command
design pattern.

~~~
cooervo
Yes, the documentation loves to use complicated concepts and is very hard to
understand. also its a ton of boilerplate code.

I think redux just became hyped because of its "time travel debugging" which
is just pure functions returning some stored values.

~~~
citrons
I also had a bit trouble learning redux (adopted quite early), but now there
is video series by Dan Abramv that goes trough entire redux features is is
easy to understand.

But the conectps in redux IMO are worth learning, made me think about my own
code different. More pure functions, less sideeffects...

------
winton
After using Redux for a while, I realized that I was creating a lot of
boilerplate to essentially (1) update an immutable store and (2) pass that
store's state to (a)sync callbacks that execute in serial before and after the
store was updated.

This lead me to the creation of DotStore ([https://github.com/invrs/dot-
store#readme](https://github.com/invrs/dot-store#readme)), along with
extensions to use it with React [1] and the filesystem [2].

"Dot prop" strings have proved to be an elegant solution to detect which props
changed on the store. Usually this means doing a regex match in
`shouldComponentUpdate`. We almost never use React's state anymore.

[1]: [https://github.com/invrs/dot-
store/tree/master/packages/dot-...](https://github.com/invrs/dot-
store/tree/master/packages/dot-store-react#readme)

[2]: [https://github.com/invrs/dot-
store/tree/master/packages/dot-...](https://github.com/invrs/dot-
store/tree/master/packages/dot-store-fs#readme)

~~~
senoroink
None of your links seem to work. Is this a private repository?

~~~
winton
Heh, very new project, thanks for the heads up. Its public now.

------
bigtunacan
I'm not going to make any claims that Redux is dead or dying; I'm mostly
oblivious to the state of React (no pun intended). I'm coming from Knockout
and Angular making the switch to Vue.

This line from the article got me though.

"plus all of its usage with other JS frameworks like Angular, Ember, and Vue"

Are people actually using Redux with Vue? Everyone I know is using Vuex for
state management for Vue.

~~~
swyx
yes i have been wondering who uses redux without react. redux tries so hard to
be a react independent library, but maybe it shouldnt. ¯\\_(ツ)_/¯ the
maintainers do not agree.

~~~
acemarke
And why shouldn't it be independent of React? While Redux and React-Redux were
developed together, the Redux core is 100% pure plain vanilla JS, and the fact
that bindings exist for a whole bunch of other frameworks shows that it works
fine that way.

Now, Dan and Andrew have suggested that in order to have React-Redux work
properly with the upcoming async React rendering, we should possibly consider
reimplementing the Redux store logic to use React component state as the
basis. In other words, you'd probably do something like `import {createStore}
from "react-redux"`. I'm not keen on that idea myself, and am hopeful we can
find an approach that will allow use of a separate standard Redux store and
still get the benefits of async React rendering down the road.

~~~
swyx
maybe what im really after is what react-router-dom does, which is reexport
react-router. stop making me wire up the core library itself, if you have a
binding it should "just work" (TM)

------
mephitix
I started using Redux with container components and dumb presentational
components - this worked and scaled well.

Eventually though some containers started to have their own state, derived
from props.

Ultimately I was left with the feeling that I wasnt really getting the full
benefits of redux (time traveling, centralized middleware, etc) without moving
all state in my app to Redux.

I think this is how teams get trapped by Redux - the pursuit of having nice
dev accordances like time traveling leads them to adopt Redux everywhere and
just by Redux’s nature (immutability, declarative actions) it ends up
complicating things way too much.

I think the article I’m most grateful for is Dan’s article on container vs
presentational components. Sticking to that philosophy let me adopt Redux and
try it out but still have the majority of my app in dumb, non-Redux
presentational components. So now it’s easier to remove Redux if I need to.

~~~
acemarke
We do try to emphasize that it's completely up to you how much or how little
state you actually put into Redux: [https://redux.js.org/faq/organizing-
state#do-i-have-to-put-a...](https://redux.js.org/faq/organizing-state#do-i-
have-to-put-all-my-state-into-redux-should-i-ever-use-reacts-setstate) .

I've certainly talked to people who literally put every single value in their
app into Redux (often in conjunction with _only_ using functional components).
I can understand why they might choose that approach, but to me that's over-
opinionated. Most of my app-type data does go into Redux, but it's absolutely
fine to use React local component state for whatever doesn't need to be
shared.

~~~
FundThrowaway
That's one of my favourite parts of Redux is how flexible it is, use a little
bit here and there where it's appropriate. The current project I'm working
uses Redux to manage all of the websocket communication but that's it.

------
sailfast
Great post and good clarifications about the future of Redux - thanks! Happy
user of Redux in both a React app and an Angular app. Makes managing state in
Angular (not to mention testing where ordinarily multiple controllers might be
involved) so much cleaner. Thank you for your hard work, maintainers!

------
quxbar
Vanilla redux isn't really useful for what most people are building. We have a
simple app for a few tabbed lists of items, filtering and sorting that list,
and taking basic state changes on the items. The first epiphany I had was
using redux-first-router to couple URL to state, with thunks to load in data
based on the parameter. That takes care of pagination and filtering on the
lists. Then we use middleware to write the API calls for our state changes,
and as a logging layer, since all of our navigation actions are meaningful
(changing sort order, bringing up a particular item, etc). It's a very simple
pattern for other developers to use, I find, and the boilerplate is minimal.

------
jopsen
This is why projects/libraries/services should list the pros/cons of using
them. So people know when something is a fit, and that it's not always a fit.

This pattern of some _thing_ becomes popular; everybody says to use _thing_;
people use _thing_ where it's a bad fit; tsunami of people says _thing_ is
broken. _thing_ keeps living.

Examples: redux, react, S3, EC2, AWS lambda, heroku, docker, angular, ruby-on-
rail, rust, golang, well every _thing_ :)

------
songzme
For those who don't know redux, here's a quick 5 min video from vimgirl.
Personally, I like her short, straight to the point approach.
[https://youtu.be/SV_reBvGKPE](https://youtu.be/SV_reBvGKPE)

It shows you redux as it is using plain javascript, without involving react,
which gave me a clear idea of what redux actually is.

~~~
mcintyre1994
The plain JS example is nice too:
[https://github.com/reactjs/redux/blob/master/examples/counte...](https://github.com/reactjs/redux/blob/master/examples/counter-
vanilla/index.html)

------
Yaggo
I hadn't considered Redux dead, but after that title from "them", I am now.

~~~
rejschaap
Or at least that it is dying, since it is "Not Dead _Yet_ "

------
iandanforth
I've had a mixed history with Redux. It always felt like a ton of overhead to
maintain on top of React. However I recently started using Rekit
([http://rekit.js.org/](http://rekit.js.org/)) which is a web-based IDE
specifically for React+Redux and I'm loving it. All the patterns the IDE
defaults to (and in some cases enforces/automates) are ones that I had to
learn painfully (and repeatedly) in other contexts. Now when I need a new
action I get the paired reducer, top level reducer tie-in, tests, all for
free. It's great! Try it out on your next project!

------
twfarland
Redux has been great, but after a few years, I've had enough of the action
creator and reducer boilerplate, and now just use Proxy objects for external
state (with a listener on the handler's setter). It's mutable but hasn't been
a problem in practice.

------
baronseng
Did anyone use dvajs
[https://github.com/dvajs/dva](https://github.com/dvajs/dva) and any comments?

------
tootie
The react context API is an abomination. How is tag-nesting an API?

~~~
mephitix
How is tag-nesting not considered an API for React? The entire point of the
new context API is to get around prop-drilling. Being able to do that and
express the intent in JSX is what it does well IMO...

~~~
hestefisk
Context to me seems like a sophisticated way of declaring global variables.
Might as well do const GLOBALS = { ... } instead of another complex API that
has to be loaded.

~~~
crooked-v
The new context API effectively makes variables available globally, but you're
still using a separate (explicitly declared) Consumer for each, so you don't
have any of the basic issues that go with using a single set of globals.

For a very simple example:

    
    
        import { UserIdConsumer } from '@/contexts'
    
        const ThisComponent = () => (
          <div>
            User ID: <UserIdConsumer>{value => value}</UserIdConsumer>
          </div>
        )
    
        export default ThisComponent

~~~
hestefisk
Not sure I follow. Where does value come from?

~~~
tym0
UserIdConsumer will call the children prop as function, UserIdConsumer could
look like this:

    
    
        const UserIdConsumer props => <Fragment>props.children(theValueYouWantAvailable)</Fragment>

