I wanted to write another answer focusing on the specific difference between Reflux and Redux. @Mijamo goes into the core of why they originated as different things and is a very good summary if you have context, but I came to this question to know specifically the difference between the two from a development perspective. Seeing as how I just went in and read all the things, I wanted to write an answer. I will update this answer with more code examples.
Flux (Quick overview)
Before we go into this, I think one thing that we should keep in mind moving forward is thinking about current Flux and how it currently handles scaling an application with many components or many different pieces of states that needs to be managed. This is a pretty good talk at React NYC: Scaling Flux that goes into the problem and the solution they arrive at is not too far off from what Reflux and Redux allow you to do but in a nutshell a big question is "What do we do when we have components that have some shared state that they all need to keep in mind of? How do we handle and scale that?" Ultimately an answer a lot of these frameworks arrive at is we need this idea of a global state. Inevitably, both frameworks introduce some similar concepts to achieve this which we'll go into below.
Because I will need to reference a comparison of Flux, I just want to show a quick overview way Flux works with the picture below:
Reflux
In Reflux, there is no dispatcher, and the View Components directly communicate via the components through actions.
+---------+ +--------+ +-----------------+
¦ Actions ¦------>¦ Stores ¦------>¦ View Components ¦
+---------+ +--------+ +-----------------+
^ ¦
+--------------------------------------+
In terms of how it differentiates itself from Flux, there is not too much. You still create your own actions and create your own stores, and you still have your stores listen to actions. I believe the biggest difference is that in order to have the View components submit actions directly to the store rather than going through a dispatcher, the Components have a store property which comes from extending from Reflux.Component
rather than React.Component
so that it has a way to directly hook into a store. i.e. this example
class MyComponent extends Reflux.Component
{
constructor(props)
{
super(props);
this.state = {}; // our store will add its own state to the component's
this.store = StatusStore; // <- just assign the store class itself
}
render()
{
var flag = this.state.flag; // <- flag is mixed in from the StatusStore
return <div>User is {flag}</div>
}
}
You also have the ability to hook into multiple stores (there is a prop I believe called stores
which takes an array and Reflux also ships with the ability edit mapStoreToState
in case you wanted to control specifically how the stores pass over state to the components.
Naturally because you are using a component that Reflux ships with, you should probably read their documentation on Reflux Component and how to properly make components with this in mind
Last thing I'll note is above I mentioned the big problem was global state and how does this address that. Reflux does have a Reflux.GlobalState
that can be contributed to as long as you set ids on your Stores. The link above goes a lot more detail into it but with this, you can access them via Reflux.GlobalState.[StoreID].[property]
where StoreID
is the id you assign the store and property
is the actual piece of state you want to access.
Redux
Redux in and of itself changes a lot of things and also kills the idea of dispatchers. Before I go really deep into it, I want to highlight the three principles they mention in their docs.
- Single source of truth
- State is read-only
- Changes are made with pure functions
In Redux, there is really only one global state you have to deal with and that is the global state for your application (addressing the big problem). While you still have actions and stores, the stores themselves are simply responsible for keeping track of their own state in the global state tree, allowing you to dispatch actions to make changes to the state tree, and allowing you to access the state. You can also still put listeners on these stores via subscribe
.
A large motivation of this goes into the first two principles. In Flux or even Reflux, if you wanted to make sure nothing was mutating the state when you didn't want it to (because technically you can access and change state in the stores whenever you want), you would depend on things like ImmutableJS to make sure you weren't accidentally mutating the state. Redux on the other hand makes it so you can only access the state via the stores/selectors and making changes only via dispatching actions (the third principle).
An interesting thing to note is that while Reflux and Flux had actions where in the stores you would listen and determine what state change to do, the stores in Redux simply dispatch a message with the payload you want and then that goes through a giant switch statement to determine what it should do with the state tree -- this is what they refer to as a reducer. This isn't any different from how Flux has reduce
in its Stores but Redux rips this concept out as its own thing and your global state tree goes through a rootReducer
(Redux ships with a nice function for you to combineReducers
and make a rootReducer
). A good way to think about it is you dispatch a change to the giant state tree and then whatever changes you want, it gets reduced or condensed to the final state you want. This actually influences how redux sets up a lot of things so it tells React how to rerender (assuming you are using Redux with React).
The data flow of Redux talked about really well in the link I mentioned above but there is also a pretty good infographic I have attached
So core differences is really
- Redux has a completely different approach to state management -- it embraces the idea that there is a global state and that inevitably if you wanted to make changes, it should just happen there in a very specific way (how you handle what components have access to what state is up to you).
- Reflux really tries to support giving components the ability to access multiple stores without having to change too much of what Flux was originally about (I would like to think Reflux is what Flux should have been).
- Redux really changes how the state tree is managed and give the
stores different responsibilities, and changes how state information
is mapped down to the components, whereas Reflux simply rips out the
middle man so you can have your components access whatever stores
they need to more easily.
Hopefully this gives more insight to the core differences between them.