hammerlab/cycledash — pull request #127 by ihodes (2014-10-18 03:44:13+00:00)
Title: Fluxification

This commit moves the Examine page to Flux, adding a Dispatcher (using
the one that comes with flux), Actions, and a Store (RecordStore).

State is canonically stored in RecordStore (the store) and queried by
ExaminePage when the store determines that it has changed. The store
gets actions sent to it via the dispatcher. The dispatcher recieves
actions from components. The flow of data looks like the below:

-> Componenents -> Actions -> Dispatcher -> Store ->

c.f. http://facebook.github.io/flux/docs/overview.html

The complexity of state management, including caching and other tricks
to speed up the processing of VCF records, is pushed into
RecordStore. This is the module which should be rather
well-tested. ExaminePage just needs to query it for the current state of
the world; no more does a component need to worry about the perils of
data management, cache invalidation, and other niggling concerns of the
physical world. ExaminePage is but a beautiful stained-glass window
looking out on that dark and mournful plane.

React components are moved into a /components/ subdirectory. The entry
point is now /examine.js.

NB: We currently still pipe handlers through the components tree, but it
appears that most Flux-style apps instead send actions directly from
components to the dispatcher. I'm not sure about this yet (for various
reasons, some below[1]), and have decided to pipe handlers through, as
before, and dispatch actions from the root, ExaminePage, instead.

Below please find a rambling tangent.

[1]: For several reasons. One: the typical way to dispatch directly from
children components is by using a global singleton Actions module which
knows where the dispatcher is because it initializes one when it's
required. This is somewhat statefully gross. This I solve via
"dependency injection", which is a silly way of saying that I pass a
Dispatcher closure (instance) into the RecordActions function, and then
pass that closure (instance) of RecordActions down to ExaminePage, which
uses it to send actions out into the world.

Another reason to shy away from dispatching actions from child
components is that it binds children tightly to a module (the Actions
module) which has a separate concern from the view/react
components. This seems undesirable. Instead, components should have
hooks into them (event handlers) which can be considered to be generic
until as far up the component chain as possible: in this case,
ExaminePage, where actions are dispatched from.

Something to think on.