React.JS and Flux ideas for practical applications

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:

Ah yes interesting, why not continue reading the web page?

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 [0]react primer draft and [1]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 [1] with one-way propagation of data through the tree of components is the ideal, meaning no this.state anywhere. However, there will inevitably be integrated components which have other state, and this should be as contained as possible using this.state and 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 REQUEST action and then one RECEIVE action, which is kinda nice because they can be tested and implemented separately, and the REQUEST action 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 [1], but definitely use the pureRenderMixin and/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 null if the sub-component is invisible). The other is to render them with a “visibility” prop and have the sub-component set a display:none style 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 shouldComponentUpdate since === will return false every 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).

  • Use shouldComponentUpdate. As far as I know there are four basic optimization strategies with shouldComponentUpdate:

    • 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 shouldComponentUpdate is just a matter of looking at the version tag for the node.

    • Finally there is the strategy of running shouldComponentUpdate fewer 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 shouldComponentUpdate to always return false, and use componentDidMount and componentWillUnmount to 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.