https://github.com/wwwy3y3/coren-example
coren example
https://github.com/wwwy3y3/coren-example
coren react react-server-render redux
Last synced: about 2 months ago
JSON representation
coren example
- Host: GitHub
- URL: https://github.com/wwwy3y3/coren-example
- Owner: wwwy3y3
- License: other
- Created: 2017-06-06T17:34:05.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-03-03T14:35:18.000Z (about 7 years ago)
- Last Synced: 2025-02-13T18:17:13.238Z (3 months ago)
- Topics: coren, react, react-server-render, redux
- Language: HTML
- Homepage:
- Size: 160 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Coren-example
This example repo shows how to serverside render React Single Page App with `coren`[Demo](https://nameless-taiga-65782.herokuapp.com)
# Usage
```sh
$ git clone [email protected]:Canner/coren-example.git
$ yarn
```## development
test in development mode, with hot-reload
```sh
$ npm run webpack-server
$ node app.js
$ open http://localhost:9393
view source to see HTML
```## production
test in production mode, with real ssr result
```sh
$ npm run coren
$ npm run webpack-server
$ COREN_ENV=pre-production node app.js
view source to see HTML
```# Explanation
## modules used
* react-router v4
* redux
* redux-api-middleware## How this example use Coren
* use `RoutesCollector` to generate routes need to be rendered
``` js
// /src/Home
static defineRoutes({Url}) {
return new Url('/');
}
`````` js
// /src/User
// server will execute db.users.find().execAsync(), get the data then generate multiple routes with path '/users/:id'
static defineRoutes({ParamUrl, db}) {
return new ParamUrl({
url: '/users/:id',
dataProvider: () => db.users.find().execAsync()
});
}
`````` js
// /src/UserList
static defineRoutes({Url}) {
return new Url('/users');
}
```* use `HeadCollector` to get title, description
``` js
// /src/User
static defineHead(props) {
const userId = props.match.params.id;
return {
title: `user ${userId}`,
description: `user ${userId}`
};
}
```* customized `ImmutableReduxCollector`
as a best practice in our team, we use immutable state in redux. so we modify some part of ReduxCollector
``` js
class ImmutableReduxCollector extends ReduxCollector {
appendToHead($head) {
$head.append(``);
// wrap state with Immutable, when rendered in HTML
$head.append(`
window.__PRELOADED_STATE__ = Immutable.fromJS(${JSON.stringify(this.state ? this.state.toJS() : {})})
`);
}wrapApp(appElement) {
// if initialState collected from components is empty, we pass undefined to store , let store.getState() be the intial state in reducer
const store = createStore(this.reducers, isEmpty(this.initialState) ? undefined : immutable.fromJS(this.initialState));
const wrapedElements = react.createElement(Provider, {store}, appElement);
this.state = store.getState();
return wrapedElements;
}
}
```in Component, we use `definePreloadedState` return initialState this component need
``` js
// /src/UserList
// 透過 server 傳過來的 db 做出 query
static definePreloadedState({db}) {
return db.users.find().execAsync()
.then(list => ({
users: {
list,
fetched: true,
isFetching: false,
error: false
}
}));
}
```## dev server
```
node devServer.js
```