Skip to content

Instantly share code, notes, and snippets.

@aesteve
Last active January 18, 2016 22:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aesteve/820ae0b3651097ea945a to your computer and use it in GitHub Desktop.
Save aesteve/820ae0b3651097ea945a to your computer and use it in GitHub Desktop.
What is flux

Flux is an architecture to help client-side application deal with data coming from several endpoints (API endpoints, websockets, user interaction, etc.).

The basic idea is that you're connecting to many endpoints, and when your "connectors" catch a new piece of data, they're dispatching actions (through a dispatcher).

Reducers are listening to these actions. When they catch an event they're interested in (let's say UserReducer catches an USER_DATA_UPDATED event), they "do something" with the action. Most often, they're just storing the data attached to the action somewhere, and returning their new "state". (their state represent a portion of the global store).

Components (views, basically), on the other hand, can be connected to many reducers (or to the whole store). Thanks to a pure function (connect), you'll describe what the component properties will be for a given state of the global store. Let's say your component only needs some users data and not pricing info for instance. You'll create a selector mapping to the "user" portion of the global store. This way, when pricing info change, your selector will be re-evaluated and return the exact same data (user info). Thus your component will stay as is, no rerender, no lifecycle method invoked, nothing. You're basically declaring which portion of the store your component is bound too (example : connect(state => {users : state.users.filter(u => u.name.indexOf('A') === 0) }) the component's users property will be bound to every user contained in the users portion of the current state, whose names starts with 'A').

The other way around : when a user clicks a button, or does something, your component just dispatches an action, which can be forwarded to the server, or also caught by reducers immediately.

This allows client-side application to work in a more functionnal-oriented way :

  • components are kinda "pure" they don't have an inner state, they just rely on properties, extracted from the reducers
  • no matter where actions (=> data) come from, the state of the reducers will be the same, thus the component will receive the same properties, thus the application will look the same
  • since everything is pretty much described as functions (dispatch an action, catching data and returning an updated state, extracting data from a store, ...). This allows to create a client-side application from small building bricks and reusable logic. (for instance : this selector is a combination of this function and this other function)
  • this is also a very declarative approach. dispatch('USER_INFO_CHANGED') connect(state => {user: state.userInfo}) is almost self-documenting. You understand where data comes from.

This also gets rid of the two-way data binding. Flux architecture looks like a circle kinda :

(dispatch) actions -> (caught by) -> stores -> (connected to) -> components -> (dispatching) actions. And looping (or not).

It's directional, and safer. If you respect the architecture, you're pretty sure you won't struggle with events triggering other events triggering other events, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment