Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Documentation #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/Design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Design
This gives you a high level overview how this library interacts with [React Router](https://github.com/reactjs/react-router) (RR) and [NavigationExperimental](https://github.com/ericvicenti/navigation-rfc) (NavExp) and explains the seperation of concerns.

### `Router`
The `Router` that is exported by this library is basically a customized variant of the [RR Router](https://github.com/reactjs/react-router/blob/master/docs/API.md#router). We customize the [`history`](https://github.com/reactjs/react-router/blob/master/docs/API.md#history) prop by supplying a `nativeHistory` and the [`render`](https://github.com/reactjs/react-router/blob/master/docs/API.md#renderprops) prop by supplying a custom `RouterContext`. Other RR Router props such as [`createElement`](https://github.com/reactjs/react-router/blob/master/docs/API.md#createelementcomponent-props) are passed through.

[`routes`/`children`](https://github.com/reactjs/react-router/blob/master/docs/API.md#routes) can be supplied to the `Router` via JSX (RR just has `<Route>`, this library has `<Route>`, `<StackRoute>`, `<TabsRoute>`) or plain objects. Route definitions are like the regular RR ones with some additional props: `overlayComponent`, `reducer`, `transition` and a `routeType`. This libary's `<Route>` `<StackRoute>`, `<TabsRoute>` just encapsulate default configurations for those additional props, plus helpful usage warnings. If you want to use plain objects, refer to the `defaultProps` that these components use.

#### `nativeHistory`
A [history](https://github.com/ReactJSTraining/history) handles and encapsulates navigation state and notifies listeners when state has changed. A `history` instance implements some methods, for example `push(location)`, `replace(location)` and `go(n)`. Read up on these methods and the concept of a "location" [here](https://github.com/ReactJSTraining/history/blob/master/docs/GettingStarted.md#navigation).

`nativeHistory` is an [enhanced](https://github.com/ReactJSTraining/history/blob/master/docs/Glossary.md?name=232#createhistoryenhancer) version of a memory history; it uses the enhancer `useNavState`. This enhancer adds the methods `create(Push|Pop|Replace|TransitionTo)` to the history's interface; the regular methods are exported prefixed with "base". The reason is that the actual methods (`push`, `pop`, ...) need additional information about the current navigation state or the current route configuration on which the operation should be performed - thus they are "created" in `RouteContext` (around L112).

#### `RouterContext`
The `RouterContext` ([RR docs](https://github.com/reactjs/react-router/blob/master/docs/API.md#routercontext)) renders the component tree for a given router state and supplies the `router` object on the [context](https://facebook.github.io/react/docs/context.html). Supplying a custom one via the `Router`'s [`render`](https://github.com/reactjs/react-router/blob/master/docs/API.md#renderprops) property is the crucial integration point of React Router and this library.

Whereas RR's `RouterContext` "just" renders the component tree given the props of `location`, `routes`, `params` and `components`, this library's `RouterContext` does more: **it holds state of navigation** (`navigationState`) **and the state of the navigation tree** (`navigationTree`) **in `this.state`.** When it receives new props ( = a navigation action has been performed), the new state and tree is calculated in [`componentWillReceiveProps`](https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops) (no additional render is performed when using `this.setState` in this hook). The next `navigationState` is calculated by **using the `reducer` defined for the given route**. (TODO: Question: i don't fully understand why it's taken from `nextState.reducer` here?)

Copy link
Owner

@jmurzy jmurzy Jun 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that one can customize the default reducers used by <Route> and its siblings. It's used by the built in reducers to run a custom reducer to create their own navigation subtree. We would probably change that API later as it doesn't allow serialization—maybe a reducerRegistry similar to how I did it for transitionRegistry.

🍺