Old Flux, New Flux
The team at Facebook that brought you React has recently updated their Flux state management system. We take a look to see what's changed.
Join the DZone community and get the full member experience.Join For Free
If you are not new to front-end development, you have heard about the evolution in Flux, Redux, and React, and, most likely, have tried it or directly used it in a project. It comes with no surprise since the popularity of React is undeniable. React’s success is attributable to its simplicity, ease of use, and a great community.
Evolution of Flux
I would also bet that most of you have used React with Redux. Both libraries go hand-in-hand so often that it’s difficult to imagine it’s possible to use React without Redux. Nevertheless, believe it or not, React is a library for building user interfaces developed by Facebook, and Redux is a library for managing application’s state developed by Dan Abramov and Andrew Clark, not Facebook. Facebook has its own library to do that job, which is Flux. Despite Flux being released about a year before Redux, and coming from Facebook itself, Redux has become the de facto standard to use with React.
Moreover, I have only met a handful of developers that actually used Flux’s package. Which always allowed me to nag them about how much I miss the simplicity of the “pub-sub” nature of Flux, and therefore having a listener in the View for being able to react to a specific change in an application’s state. Something that, in my eyes, got lost with Redux.
To achieve this in new Flux, a Store, after processing an Action (event), must “manually” emit a new event, that will be listening in the view, which will allow us to trigger a callback function to react to that change. Despite adding verbosity and certain complexity to the code, it was a beautiful tradeoff to avoid the connect binding of Redux, that although it works nicely most of the time, sometimes forces the developer to use the
componentWillReceiveProps lifecycle method to distinguish what props have actually changed, falling into if nightmare inside the method, to check what exactly changed in props.
Of course, Redux brought some great concepts, such as reducers being pure functions, immutable state (a new state is generated instead of modifying the existing one), and some, in my opinion, more about cosmetics and ‘good sounding’ statements, such as single store === single source of truth.
Recently, when coming back to the Flux documentation, I was surprised to see no reference to the pub-sub implementation I mentioned before. It was just gone. Instead, all examples only referenced stores that extend ReduceStore, from ‘flux/utils’. Doing some digging, I ran into this closed issue on Flux’s GitHub repository. Basically, Flux implemented their own version of Redux, where stores/implements a reduce method that is a pure function which returns a new state of the store. Because of this, I thought it would be interesting to compare how Flux used to be implemented, and how it is being used now.
In this public repo, you have a working example of both data flows. In `AppContainer.js` you can find two React components
AppViewNew being rendered. To see the full implementation, feel free to clone the repository and play around with it. Here, I would like to only focus on the difference that appears in the view component.
In case of the `AppViewNew.js`:
Here, we find some boilerplate with the static functions
calculateState, nevertheless, in the components
ItemList we will have access to the State defined here via
this.props. And, most importantly, whenever the store updates its state,
items will get magically updated. Which, in this simple example, looks like a great thing, but when the complexity of the application grows, this can bring some headaches to the developer.
Now, in case of `AppViewOld.js`, what we will find is:
Here we see much more boilerplate, especially when we manually subscribe and unsubscribe from Actions, using React component lifecycle functions. Nevertheless, the legibility of the code is simpler. We see to what events (or actions) this particular view will react, and, more importantly, what will be the effect on the view once these actions happen. In this case, it’s the function
refreshItems that applies the only change to the state of the view. Moreover, we could set a different callback for ITEM_ADDED_OLD and ITEM_REMOVED_OLD actions, both of which interact with the same part of the store’s state; something that we do not have with the first approach, where we only know that items have changed, but not if a new item was added, or if some item was deleted from the list instead. In fact, to actually differentiate this we would need to use the
componentWillReceiveProps lifecycle function, with a quite ugly IF comparing the old state and the new one.
Published at DZone with permission of Roman Predein. See the original article here.
Opinions expressed by DZone contributors are their own.