Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is an architecture overhaul designed to fix the issues specified in the "Cons" section of the readme, among others.
🚧 WIP 🚧
Planned changes:
Action generation and dispatching
I like how Actions are generated via function calls, but dealing with the parameters in the
data
attribute are a pain and is error prone. I would like to see these become more like normal function calls (with positional arguments); perhaps using Node.js EventEmitter events with bindings?I would also like a more declarative style of Action handling within the Stores, rather than a big if/switch statement.
Dispatcher/Component binding
I want to switch to something more like the "traditional" Flux architecture, where components (and sub-components) listen to events from specific stores to be notified of changes and then call a method on the store to generate its state. This avoids Stores having to format data to correspond with the app's state, further decoupling these systems. Stores will be made available from the dispatcher based on a name (e.g.
this.dispatcher.store('image')
).Furthermore, Stores will be able to access each other (probably by injecting them into constructors) so that they can access data from one other. Caching and data access will happen downstream in lower-level APIs. [Update: since Stores emit events, perhaps its best to share lower-level APIs instead, and make Stores independent.]
This allows Stores to share information when appropriate, resolves the Dispatcher race condition issues, and allows Stores to push data into components when appropriate.
Server data loading
Since components will now fetch their initial state from the stores, the server strategy will be to pre-load Stores with the appropriate data. The actual methods on the Stores and their lower-level APIs will return promises, so the server will be able to tell when things are done loading.
We will send preload data to the client, but instead of passing it to the top-level component, we will prime the Stores and then pass those to the dispatcher (which is passed to the component). The components'
getInitialState
calls will then return the same data as on the server.Route prepping
Currently, the
RouteStore
only parses URLs and sets a portion of the state that indicates which page to show, but says nothing about what is on that page. Other Actions are dispatched when sub-views are mounted in order to fetch the appropriate data. I'm toying with the idea of having the routing layer also fetch the initial data for that route, similar to theresolve
property in the Angular router. This will decrease the number of events that must be orchestrated in order to get a proper view set up, especially helpful on the server (when we want to do it all at once anyway).