add initial state support (#574)

* add initial state support

* clean up initial state from window

* fix initial state if none
This commit is contained in:
Yoshua Wuyts
2017-10-20 16:30:58 +02:00
committed by GitHub
parent 2f970403d5
commit 5561566dd5
2 changed files with 35 additions and 3 deletions
+25 -2
View File
@@ -225,6 +225,10 @@ Choo comes with a shared state object. This object can be mutated freely, and
is passed into the view functions whenever `'render'` is emitted. The state
object comes with a few properties set.
When initializing the application, `window.initialState` is used to provision
the initial state. This is especially useful when combined with server
rendering. See [server rendering](#server-rendering) for more details.
### `state.events`
A mapping of Choo's built in events. It's recommended to extend this object
with your application's events. By defining your event names once and setting
@@ -295,8 +299,8 @@ To can navigate routes you can emit `'pushState'`, `'popState'` or
`'replaceState'`. See [#events](#events) for more details about these events.
## Server Rendering
Choo was built with Node in mind. To render on the server call `.toString()` on
your application.
Choo was built with Node in mind. To render on the server call
`.toString(route, [state])` on your application.
```js
var html = require('choo/html')
@@ -314,6 +318,25 @@ console.log(string)
// => '<div>Hello Node</div>'
```
When starting an application in the browser, it's recommended to provide the
same `state` object available as `window.initialState`. When the application is
started, it'll be used to initialize the application state. The process of
server rendering, and providing an initial state on the client to create the
exact same document is also known as "rehydration".
For security purposes, after `window.initialState` is used it is deleted from
the `window` object.
```html
<html>
<head>
<script>window.initialState = { initial: 'state' }</script>
</head>
<body>
</body>
</html>
```
## Optimizations
Choo is reasonably fast out of the box. But sometimes you might hit a scenario
where a particular part of the UI slows down the application, and you want to
+10 -1
View File
@@ -45,7 +45,16 @@ function Choo (opts) {
// properties that are part of the API
this.router = nanorouter({ curry: true })
this.emitter = nanobus('choo.emit')
this.state = { events: this._events }
var events = { events: this._events }
if (this.hasWindow) {
this.state = window.initialState
? xtend(window.initialState, events)
: events
delete window.initialState
} else {
this.state = events
}
// listen for title changes; available even when calling .toString()
if (this._hasWindow) this.state.title = document.title