Hi James! Dan and I came at it from slightly different perspectives, so I'll describe the arc of Redux history as I saw it.

Before Redux, I created a Flux library called Flummox. This was during the time that a new Flux library was coming out every week. The initial motivation for Flummox was that I needed to do server-side rendering. Few of the existing libraries supported this because they relied on singleton stores. I tried to design Flummox as a thin layer on top of Facebook's Flux dispatcher, with a store API that mirrored the React component API (e.g. stores had a setState method that automatically emitted a change event). In retrospect, there were a few unfortunate design choices, but there are three that really stuck: the idea of action creators as functions that return action objects; using React context instead of singletons; and using React components (and higher-order components) to connect to your stores (instead of mixins as most libraries did at the time). All of these points influenced the design of Redux.

Meanwhile, Dan was working on a talk for React Europe 2015 on time-travel and hot reloading Flux stores. Dan was a Flummox user in early 2015, using it as part of React DnD. This is how I originally met him.

There were a few other cool Flux libraries floating around at the time. I remember NuclearJS and Om being especially influential. The idea of a more functional Flux, where updates are expressed as functions of the previous state, and state is kept in a single immutable object — those concepts predate Redux. I remember lots of discussion with Dan and others in the community about how to apply these concepts to the Flux pattern.

Dan's original version of Redux contained the key insight that there's really no need to have multiple, stateful stores in Flux. Instead you had "stateless stores" that returned a new state given the previous state and an action. We later, of course, renamed these to reducers. This initial version was pretty cool, and could do time travel and hot reloading, but it didn't have some of the other aspects of Redux that we know today. There was no single, immutable state value. On every dispatch, Redux would iterate through every "stateless store," compute the new state for that store, then combine the states together. There was also some logic to only emit change events to components that had subscribed to a specific store, for performance. (This was later replaced with selectors and shouldComponentUpdate optimizations.) There was also no such thing as middleware — there was basic async support built-in, which we later extracted into redux-thunk.

An important bit of the original Redux was the lack of waitFor. One of the things previous functional Flux experiments struggled with was how to account for this feature, which in traditional Flux is used to deal with dependencies between stores. Dan recognized that this can instead be solved instead using composition. (https://gist.github.com/gaearon/d77ca812015c0356654f)

This was a eureka moment for me. Building off Dan's idea, I realized that you could also use function composition to avoid having to keep track of many "stateless stores," and instead combine them together into one. I stayed up all night and sent Dan a prototype illustrating this concept (by happy coincidence, this happened on Dan's birthday!): https://gist.github.com/acdlite/9f1b5883d132ad242323

There's some weird terminology in that prototype, but in it you will find the genesis of many of the key concepts that make up Redux today: reducer composition (combineReducers), a single state value, and selectors. This updated design also had the happy side-effect of dramatically reducing the amount of code needed to implement Redux, as anyone who has completed Dan's Egghead Redux courses can tell you.

Another key concept in Redux, middleware, came soon after. If you're interested, I encourage you look back at some of the early PRs and issues. There was lots of back and forth between Dan and me (and other collaborators) about how to make Redux extensible, so that it's hard to remember who came up with what exactly. The way I remember it, Dan came up with the idea of what was later called "store enhancers," which we also sometimes called "Redux inception" (turns out, this is just a flavor of the Elm Architecture). I came up with middleware based on a pattern used by Flummox internally to support promises. The truth, though, is that these patterns were the result of extensive collaboration and experimentation, so it would be wrong to attribute them to any one person.

Middleware and enhancers are perhaps the two bits of Redux that I'm most proud of, because it allowed us to keep Redux really small and focused, and enable amazing community projects like redux-saga and redux-observable. In other words, middleware and enhancers effectively killed the new-flux-framework-every-week trend because you no longer had to create an entire library to implement a single idea. Without this, I doubt the Redux community would have lasted as long as it has.

So that's the basic overview. There's so much detail that I've left out, but I've gone on too long already. Perhaps I'll cover the rest in my response to other questions :)

Terrific answer by Andrew. I'd just add he's being humble, and middleware was mostly his design. I was just merging whatever PRs he was sending because I was busy trying to get my conf talk demo working :P.

But seriously, I suggest to read early issue and PR discussions, they're a lot of fun to revisit now.

Teams at Facebook can use whatever tech they want to use. Some internal projects use Redux. I think some parts of Facebook.com website also started to use it but those are subject to change because sometimes people want to customize it for their needs, or might replace that version of the product code with something else altogether. Don't forget Redux is super tiny so adding or removing it is not a huge deal.

How would you recommend to learn Redux for someone who has small amount of experience in Functional Programming?

I comfortable with React and now I want to use Redux with it, because approach I currently apply uses events to notify React components when my models have changed, kinda like Pub/Sub bus. What I've noticed this approach doesn't scale very well and it's hard to reason about code when code base becomes bigger. I've read few articles about Redux and I think it can help me.

I have a lot of experience with OOP code. I worked with Ruby/Rails and focused a lot on good object oriented design.

I don't have a lot of experience with functional programming in general. I have some experience with Scheme, mostly for learning recursion.

I kinda understand lambda calculus and ideas behind it, I even wrote Applicative Y-Combinator using things like Tennent's Correspondence Principle and so on.

Also I have some experience with Haskell. I know what "Currying" and "Partially applied function" concepts mean and what they for.

For me it looks like that Redux is heavily based on ideas from Functional Programming.

I think my question consists from 2 parts:

What learning path would you recommend in order to be comfortable with ideas on which Redux based on?

What knowledge/skills should I have in order to be really comfortable working with Redux and build applications using it?

I know I wrote a lot here, but I think it will help you give me more specific advice using provided information.

If you thinking that there is some programming language where some particular ideas expressed better, feel free to mention it. I've found that sometimes it's very beneficial to get to roots of some idea (yes, I do have a lot of free time). For example learning Smalltalk made me a better Ruby developer and OO developer in general.

You definitely don't need to know lambda calculus to learn Redux. Or Haskell, or Scheme, or the difference between currying and partial application :)

In fact, one of the virtues of Redux is that it serves as a nice introduction to functional-lite programming, utilizing concepts like immutability, pure functions, and unidirectional flow. Since you already know React, it should be even easier for you to pick up Redux. (I always caution people against learning both at the same time. You've gone about it the right way.)

Once you learn Redux, learning those other concepts will become all the easier. As an example, neither Dan nor I really understood Elm until after we had come up with Redux!

EDIT: to answer your final question, Elm is a great first FP language, and a perfect stepping stone once you've mastered Redux

Dan and I weren't too familiar with Elm when we first started working on Redux. We had read the Elm Architecture document, but for whatever reason (perhaps our unfamiliarity with its ML syntax) neither of us really understood it. It was only later, after coming up with "reducers" and reducer composition independently, did we realize how similar Redux is to Elm.

The biggest difference is that the Elm Architecture is fractal. An Elm model's structure mirrors the structure of the UI, via composition. In other words, most Elm update functions (reducers, in Redux parlance) have a corresponding view.

Redux also uses reducer composition, but its composition does not mirror the composition of React components. In fact, we typically recommend that Redux reducers do not correspond directly to components. Those types of reducers are usually best implemented using local state.

There is 4.x branch hanging around that we never finished but that I hope to ship eventually. It almost doesn’t change user facing API but it in my opinion completes the extensibility design in Redux, fixing a few mistakes we made along the way.

After it lands, we should be able to make minor implements to the API like passing the state to subscribers, without hurting the extension ecosystem.

Honestly I don't expect Redux to move beyond that. There is value in maintaining backwards compatibility, and I don't think we've made too many mistakes anyway. I'm pretty happy with how Redux turned out to be, and I think its scope is well defined and closed.

Personally, I will be interested in making React component state more competitive with Redux. I'm also interested in declarative data fetching solutions like Relay. I hope that we can find a sweet spot between them and make React better with ideas from both.

Dan responded as I was typing my response. Happily we touched on many of the same points!

The not-so-secret thing about Redux is that, while the larger community has been and remains incredibly active, the core Redux library itself hasn't changed much at all since last summer. In my view, Redux is essentially complete. Most of the innovation around it will continue to come in the form of third-party extensions, including projects like Redux Saga and Redux Observable. There are a few things that I would still like for Redux to solve. One is to make it easier for Redux-like patterns to be used at the component level. It's likely that this problem is better solved at the React level; however, I think it'd be great if the wide ecosystem of existing Redux middleware and enhancers could be scoped to work for an individual component. We're actually pretty close to making this happen. I believe this PR is the only real blocker (related to the INIT action): https://github.com/reactjs/redux/pull/1702

The next thing for state management? Well first, I'd like for people to stop putting everything into their Redux store unnecessarily. I like to imagine the different types of application state as a spectrum. On one end is highly local state, things like animations or form input values. On the other end is cached representations of external data, e.g. fetched via GraphQL or REST. In the middle is state that doesn't necessarily correspond to a specific component's lifecycle, or is shared across multiple parts of an app. This middle bit is where Redux really excels. For local state, I'm excited about ways to make React component state more functional. MobX seems to be doing some good work here, though I must confess that I haven't used it extensively. On the other end, for managing external data, I'm extremely bullish on declarative data fetching solutions, especially Relay which I think is just fantastic. I encourage you to check out Relay if you haven't already!

I realized it was getting popular when it was still a proof of concept for my upcoming talk and had about 300 stars. I went to bed and woke up next morning to a list of 15 small Redux examples that popped up on the net. It was very confusing because we didn’t really document the library well at the time, and I didn’t expect anyone to start using it yet. That’s when I knew something was happening. Later I gave my React Europe talk, and it just kept growing. This was when I knew I’d better document it, so I raised some money on Patreon, and worked on examples and documentation for a few months.

I was excited to be solving problems I was interested in, such as hot reloading and time travel (https://www.youtube.com/watch?v=xsSnOQynTHs). I am also continually impressed by all the amazing work happening in the ecosystem (redux-saga, redux-observable, redux-devtools-extension, etc). It’s humbling to have played some part in this.

I try to not get emotionally invested into Redux or its ecosystem because once something is large enough, it takes on a life of its own, and you can just watch it happen and maybe sometimes correct its course. I try not to feel guilty about the churn experienced by people who took Redux too seriously and tried to use it even when it didn’t work well for their use case. I also try not to get upset when somebody bashes Redux. I understand that now that it’s big, many people are going to have to use it against their will, or have to learn it because it’s trendy, and bump into many abandoned experiments or frankly bad ideas in the ecosystem. Overall I’m very grateful to the community who built on top of Redux, and if it helped move some amazing techniques from functional programming closer to the mainstream audience, it makes me happy.

I knew Redux would be popular pretty much the moment I saw Dan's original version. I had a semi-popular (at the time) Flux library called Flummox, so it would have been easy for me to be stubborn and deny the obvious benefits of a reducer-based Flux. In one of my proudest moments, I instead quickly deprecated Flummox and jumped on the Redux train. Zero regrets. I caught some flak for this (reasonably—I could have done a better job transitioning Flummox users to Redux) but it ended up being a great decision, both for me personally and for the Redux community as a whole.

So my open source advice is this: you are not competing against other libraries. Well, I mean, you are, but if you focus mostly on "beating" the other guys and gals, you're eventually going to fail. Work on finding the best solutions, regardless of whether that's by collaborating on someone else's project or starting your own.

Redux is great and has given a new vocabulary for talking about things that is very functional and great. But middleware is an anomaly.

The idea that you can dispatch an action that will asynchronously dispatch other actions is very simple - but it muddles the idea of what an action is. It also confounds the search for what interleaving semantics are applied - for example - after I dispatch actions A and B, the store may recieve [B A' A'']

I find that it's best if Actions are thought of as items that are sequentially reduced into the store, and if a higher level streams library such as RxJS is in charge of interleaving streams with whatever semantics the application needs.

I think Redux is great in its core focus, but RxJS is great at controlling the behavior of an aggregation of streams, and is more flexible than middleware, so I recommend keeping asynchrony out of actions.

But I'm glad so many people have found their own particular ways of using it. And I love how it pushes the few modules of my system that are not pure functions out to the periphery.

We didn’t want to prescribe something like this in Redux itself because we know a lot of people are not comfortable with learning Rx operators to do basic async stuff. It’s beneficial when your async logic is complex, but we didn’t really want to force every Redux user to learn Rx, so we intentionally kept middleware more flexible.

I agree that the difference between a "dispatchable" (something you pass to the dispatch method) and a proper "action" (the actual object which is sent to the reducer) can be confusing. We struggled with the right terminology for distinguishing these concepts in the docs. We landed on "async actions" and "actions" but I've never been that happy with those terms.

Observables are, indeed, a great abstraction for dealing with asynchronous control flow. Have you heard of Redux Observable? It seems to be exactly what you're looking for.

Also, as I mentioned in a different response, "[the] reason the middleware API exists in the first place is because we explicitly did not want to prescribe a particular solution for async." My previous Flux library, Flummox, had what was essentially a promise middleware built in. It was convenient for some, but because it was built in, you couldn't change or opt-out of its behavior. With Redux, we knew that the community would come up with a multitude of better async solutions that whatever we could have built in ourselves.

I'm only in my third week so I'm still in Bootcamp. (Bootcamp is Facebook's onboarding program for new engineers. It typically takes about 6-8 weeks, and it's used to both familiarize yourself with Facebook's product and engineering practices, and also to help you figure out what team you want to join.) Once I'm done with Bootcamp, I'll be joining the React team—which is exciting for many reasons, including that I'll be on the same team as Dan!

I doubt Redux will be be affected. However, one of the negative consequences of Redux's phenomenal success has been a trend away from using React's component state. There's a common misconception that using component state is bad or an anti-pattern because it's not as pure or functional as a Redux reducer. But not everything belongs in a global Redux store, and local component state is often the more appropriate place for many kinds of state in your app. I believe what people are really responding to is the awkwardness of the setState API, which has some edge cases and quirks that can be confusing. (See this Twitter thread for an example: https://twitter.com/acdlite/status/778268473772285952) The React team is interested in exploring ways to make the state API more functional and "Redux-y."

I would say that some aspects of Redux are similar to Elm Architecture (https://guide.elm-lang.org/architecture/). In particular, Redux reducers are similar to "update" functions in Elm, and Redux combineReducers() is a helper for a pattern that is also used for creating a hierarchy of update functions on Elm. The major difference is that Elm Architecture is "fractal", that is, it usually describes hierarchical UI, and like React components, always nestable. In Redux, however, there is always a top-level "entry point" (store), and so some things inherently live on the top level (such as middleware). This makes it harder to reuse components coupled to Redux because they assume a specific top--level state shape, or a specific middleware. Elm Architecture also models complete UI, whereas Redux is typically used solely for the "model", and the role of UI is often given to React. The differences between React composition model and Redux also contribute to React/Redux being less cohesive as a whole than Elm Architecture. As for historical context, neither me nor Andrew fully understood Elm Architecture when we were working on Redux, and only realised the similarities post factum. Nevertheless we're happy to direct people interested in such patterns to Elm which is worked on by smarter people than us.

You can get pretty far without a state management solution like Redux, but for any non-trivial app, I wouldn't recommend it. But as I've said in a few responses already, I don't think it's wise to put everything into your Redux store.

The rule of thumb I follow is: when in doubt, implement your state using React component state (that doesn't mean you can't use a reducer). Only move it into Redux once it becomes necessary.

Yes! GraphQL is amazing, as anyone who has played with a GraphiQL playground can attest.

To really take advantage of GraphQL in a React app, you need some sort of centralized store for normalizing and caching all your data. At OpenGov, where I previously worked, we used Relay in production since September of last year. It's a fantastic solution for declarative data fetching. I don't think we ever had a bug related to data fetching hit production.

There is some awkwardness when you first get started with Relay, particularly around mutations, which still sometimes confuse me. I occasionally hear from people who are turned off by the verboseness of some of Relay's APIs. If that's your reaction, I encourage you to look past it and give it a shot. In my experience, Relay offers an incredible number of features for just a bit more typing. Relay 2 (an upcoming rewrite of Relay's core) will solve some of these problems as well, in addition to some great performance improvements.

I recommend learning Elm to pretty much every front-end developer. It's great that FP-style patterns in JavaScript have become more popular, and I'm absolutely thrilled that Redux has played a part in it, but there's only so much FP you can do in JS given the limitations of a language. Elm is an ML-style, purely functional language, so you'll get to learn things like pattern matching, algebraic types, and "immutability everywhere" that aren't possible with JavaScript.

Whether you learn Redux or Elm first probably varies from person to person. Dan and I both didn't really understand Elm until after we had created Redux and "accidentally" (subconsciously?) borrowed some of its ideas. We've heard from other people who report the same. So if learning Elm is overwhelming, give Redux a try and go back to Elm later to get the full experience.

I use React Router. I've had quibbles about some of its API decisions in the past, but on the whole it has served me very well. I'm really excited about the upcoming API in version 4!

In my view, routing isn't a central piece of most React apps, so I wouldn't worry too much about whether your particular routing solution is the absolute best one out there. I will say, though, that the React Router team is smart, hard-working, and committed to solving the community's real world problems.

I usually say no. Component-local state does not belong in Redux because Redux is a global store. It has no awareness of a component's lifecycle, and it's very easy for multiple components to accidentally write to the same slice of Redux state.

Instead, we're looking for ways to make React's state API more functional and Redux-y, so people are less tempted to abuse Redux :)

Valid exceptions include when state serialization/deserialization is really important, or if you want to use the Redux DevTools. Though I think there are better solutions to these problems out there, waiting to be implemented.

Regarding my role at Facebook, it's currently my fourth day as an employee, so for now I'm part of something called engineering bootcamp, which all new engineers participate in. After that I'll be joining the React team with Dan, which I'm super pumped about!

Have you got around to playing with state management JS libraries other than Redux? How would you say they fare against Redux, or better what are a couple of things that a state management library other than Redux does better than Redux; and what are a couple of things that Redux does better than the counterparts?

I was wondering what the relationship between ImmutableJS and React/Flux is like at facebook since they are both developed in house. I feel like ImmutableJS is a little overused sometimes but I was wondering to get some insight into how it is used at facebook and when you think it is appropriate for a Flux or Redux app

Speaking personally, I am a big fan of Immutable. The reason I haven't used it more is that it's a bit awkward to navigate a codebase that mixes immutable and non-immutable values. It's also awkward having to use .get() to unwrap an immutable value. To fully experience the benefits of immutable data, you'd need first-class language support so that it's possible to use it seamlessly everywhere.

I think it's a great fit for both Redux and React. One problem, though, is that it makes things like serialization and debugging a bit of a pain—again, because it's not a feature of the language.

So while I don't use Immutable everywhere in my apps, it's great for those areas in which it does work.

I would add that Immutable also has its own pitfalls. Like when people hope it improves performance but call toJS() before rendering which completely defeats its purpose, as toJS() allocates a ton of objects with different identities every time. Or when people try to set fields on Immutable objects, or try to use it with the spread operator.

I would say that if plain objects and arrays work well for you, stick with them. Don't use Immutable just because somebody else does. If you want to introduce it for performance, make sure to measure your changes so that you don't regress by using it incorrectly.

Hi Dan, I started learning ReactJS and now feel comfortable with the library. I know meteor fundamentals too. But I am facing a wall trying to create event based transitions from one component to another in SPA. Is redux the answer ? I know nothing about it yet. If yes, what are the best resources to learn?

If you mean rendering a different component when an event fires (e.g. user clicks a button), normally you would call setState() from the button’s event handler, and render something else. Here is an example: https://jsfiddle.net/uokq5ggq/. Thinking in React is a good guide explaining how state works in React.

Hi! I would recommend the opposite: learn React—how its component model works, how data flows through an app, and how setState is used to update—before digging into Redux. I believe that is the best avenue for success.

Although Redux can technically work with any UI library, its design was heavily influenced by its relationship to React. For example, both libraries promote immutability and unidirectional data flow.

My dream job. (No, seriously, it was my dream since about maybe two years ago, before I sent the first PR.)

In terms of what it's actually like, our work is generally pretty visible. Lately I've been working on Create React App because a lot of people in the community are frustrated by complicated tooling. I also send some PRs with improvements and bugfixes to React. For example I added a Chrome Timeline integration to the performance tooling that will be out in 15.4.0.

I live in London so I talk to the team once a week via a conference call to sync up on tasks and priorities. I try to publish our meeting notes on https://github.com/reactjs/core-notes.

I used Redux a bit about a year ago and haven't looked at it again until very recently. I'm wondering if there are any Redux specific tools/middleware in the ecosystem that you see others commonly using together? Any that you don't mind endorsing?

One of the most common pain points is complex asynchronous behaviour since Redux was designed for synchronous updates. I think redux-observable is amazing if you're into Rx. If you're not, redux-saga is a decent alternative. But don't go for them unless you actually have complex asynchronous code!

Agree with Dan! While I haven't personally used Redux Observable or Redux Saga in a large app, I think they're an amazing realization of the vision we had for middleware last summer. The reason the middleware API exists in the first place is because we explicitly did not want to prescribe a particular solution for async. Redux Thunk is promoted in the docs because it's the absolute bare minimum solution. We were confident that the community would come up with something different and/or better. We were right!

[1] What is your favourite approach for managing routing - do you recommend coupling routing with the layout similar to ember router or react-router or would you recommend for a minimal router that just intercepts history change and updates the state tree and lets the components handle the rest of the logic.

The context is a portal like application having routes in the order of a hundred.

[2] Do you have any high level recommendations for structuring the state tree ? While it is understandable that it should be as normalized as possible, I am more concerned about information that denotes the current state of the application. Does it make sense to have a subtree that identifies what is currently relevant to the application ?

I'm building my first App with React+Redux and I fear I'm doing an anti-pattern. I use a middleware to perform my network requests (something like this https://github.com/agraboso/redux-api-middleware). So whenever I need to perform a request, I have to dispatch an action. Thus, I feel like my actions become just like regular functions, I may dispatch them even if I don't really need to update the state. Does this look like an anti-pattern, or does dispatching actions for basically any tasks make sense ?

First of all, don’t worry about “anti-patterns”, just do what makes sense to you as long as you don’t ship too many bugs. There is a whole industry (educational content, conferences, consulting) revolving around selling “best practices” and cures for “anti-patterns” so my advice is to be chill about them ;-)

As for your specific question, it depends. If most of my network requests don’t end up as useful actions changing the state, I wouldn’t use middleware for them, and just do them directly. However if most of them change the state, but a few don’t, I might use middleware for consistency. Don’t worry about “anti-patterns” and use your best judgement.

Ask about

Hosted by

About

Redux is a predictable state container for JavaScript apps. Andrew Clark, co-creator of Redux, is hosting this AMA to answer any questions you might have. Andrew recently joined Facebook as a front-end engineer. It's a great opportunity for everyone to get in touch with Andrew and have his insights on Redux and various other topics.