May 27, 2015
Here’s a list of ideas and techniques I’ve used when working with ReactJS and Flux. There are two sections: general suggestions of how to get good results, and notes from optimizing for slower hardware. Hopefully they provide a little bit of insight for when you’re looking at all these new concepts and going:
It’s difficult to say which of these items if any would definitely be “best practices” but they are available here for reference. Use at your own discretion and happy coding. Several ideas are from react primer draft and tips and best practices, both good resources to introduce and guide learning on the subject.
General suggestions of how to get good results
This has been said elsewhere, but get as much state as possible into one place in your application. With Flux this is the store(s). The first diagram from  with one-way propagation of data through the tree of components is the ideal, meaning no
this.stateanywhere. However, there will inevitably be integrated components which have other state, and this should be as contained as possible using
this.stateand callbacks. Also, any state which is definitely only significant to the one component (such as the open/closed state of a dropdown menu in many cases) can be kept internally without a problem. With Flux this leads toward fewer or even no meaningful state updates happening outside the standard data flow, which is very nice.
Some action creators get data from AJAX and pass it along by dispatching an action. There is a way to do this with one
REQUESTaction and then one
RECEIVEaction, which is kinda nice because they can be tested and implemented separately, and the
REQUESTaction doesn’t have to have any callbacks. Another option could be for the action creators to attach promises with each asynchronous action. Then the stores or a service could unpack the data before updating the state. I haven’t actually used that method and there are cases where it doesn’t provide as much flexibility (simultaneous AJAX actions may cause a “cannot dispatch in the middle of a dispatch” error), so try at your own risk.
Notes from optimizing for slower hardware
Another point from , but definitely use the
pureRenderMixinand/or implement the same kind of behavior with
shouldComponentUpdate(more on that below).
I didn’t realize for a while that you shouldn’t just run the dev source through a minifier for production. With so much relying on pure JS interpreter speed, all those great log messages and debug exceptions make quite a difference. Make sure to build or copy the actual production script when using React in production.
There are two basic ways to show or hide sub-components based on UI state. One is to leave them out of the render (I’ve used a ternary expression that returns
nullif the sub-component is invisible). The other is to render them with a “visibility” prop and have the sub-component set a
display:nonestyle internally. The first method keeps the DOM small and clean, but it means more DOM manipulation each time you show or hide the sub-component. The second is more efficient if the sub-component visibility changes often, but it means more DOM elements in the page at any one time (although some are invisible). When optimizing, use the strategy that is more appropriate for the situation.
Don’t put complex literal props inline. These cannot be used with
falseevery time. Maybe you shouldn’t use literal props at all, but that is if you want to set up constants for everything (usually not a bad idea).
shouldComponentUpdate. As far as I know there are four basic optimization strategies with
One is to split up complex props into lots of flat value props, and just check through each one. I would think this can get verbose and maybe a little less efficient, but doing a bunch of
===checks should get pretty good performance with little additional code complexity.
The second is to use a library like ImmutableJS or Mori to build an immutable state tree and update it through controlled methods. This adds a dependency and some not-very-serious overhead but enables pleasant management of an immutable state object that can be compared before re-rendering quickly and easily. The argument to use an immutable state object is much stronger if you have to implement some kind of undo/redo functionality, but either way it’s a great idea in many situations.
The third is to hand-roll some kind of version checking in each
shouldComponentUpdate. I feel like this has the potential to be a very lean strategy CPU-wise but it is also a bit more complicated to maintain. Basically you add a UUID version tag to each node in the state tree you want to optimize, and whenever updating that node you also update the version tag. Then
shouldComponentUpdateis just a matter of looking at the version tag for the node.
Finally there is the strategy of running
shouldComponentUpdatefewer times. This is where you might use internal state in lower-level components, and refs to skip typing in a textbox. Another option is to set
shouldComponentUpdateto always return false, and use
componentWillUnmountto set up and clean up DOM elements that are directly manipulated from
componentWillReceiveProps. These are mentioned at the end of the list because for all but trivial cases moving state out of the standard flow will make code more complicated since synchronization between the two state repositories is now a requirement. Before using them take some time looking into alternative solutions.