Skip to content
This repository has been archived by the owner on Nov 24, 2022. It is now read-only.

Rationale

Nick Dreckshage edited this page Jan 19, 2016 · 1 revision

This library aims to solve a set of SPA (Single Page Application) problems introduced by the complexity in coordinating three ideas simultaneously: routing, global application state, and data fetching.

  • Routing: Using routes in client side applications is inherently complex; developers must keep the current state of routes in addition to often already cumbersome application state. Because of this, we often end up writing two layers of logic in order to deal with what would be easier thought of as one piece of state.

  • Global Application State: Reducers allow us to logically separate our state and isolate its mutations to single points in which we can reason about them easily; however, they make it difficult to have an understanding of overall application state, a problem that magnifies with the introduction of routes. There are a myriad of scenarios in which we want to recall state from previous routes or check that our current route isn't divergent from our intent.

  • Data Fetching: Adding remote data sources to the mix complicates our applications further. Applications often require prerendered or cached material for performance optimizations as well as various responses in the face of authentication and authorization. Coordinating this manually creates additional burden in maintaining our state in a sane way.

Route Based State Organization

By fundamentally organizing our state based on the routing structure of our application, we can declare what decisions and intentions our application must make without complex layers of logic. This library does the following in an opinionated way:

  • Organizes Redux reducers based on routes - This simplifies overall application state, and provides more structure for single page applications.
  • Allows for automatic nested reducers - When a nested route changes, the corresponding level of state is cleared and the old reducer is replaced with the reducer for the new route.
  • Coordinates top level application state - State associated with the parent route reducer is preserved, so the developer persist certain state (current user objects, etc), a level higher.
  • Keeps reducer implementations intact - There's no change to how reducers are normally written. Nested structure is automatic and in the background. Reducers are still isolated, pure, and easily testable.

First Class Data Fetching & Inverse Lifecycle

Co-located component data fetching makes the most sense with a sophisticated, declarative data fetching service (e.g. GraphQL, Falcor, Om Next) in which queries are built through component hierarchy. Doing so can eliminate many of the problems outlined above; however, not every organization or existing platform is capable of supporting this structure. When dealing with standard REST endpoints, it's intuitive to handle resources at the router level.

This library implements a Universal data fetching API to achieve the above under the current structure of client side REST. It allows developers to have fine grained control over when and what to render under a route on the server and client. A single API is used to handle errors and redirect users.

Example: On the server, we're able to achieve blocking fetch to render top of page content, while on the client, render preview templates immediately and fetch asynchronous data to complete the bottom of page content.

Clone this wiki locally