Skip to content

Instantly share code, notes, and snippets.

@alexfedoseev
Last active Aug 29, 2015
Embed
What would you like to do?
Redux: server initter
/* app/libs/initters/server.jsx */
import React from 'react';
import Router from 'react-router';
import Location from 'react-router/lib/Location';
import { combineReducers } from 'redux';
import { applyMiddleware } from 'redux';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import middleware from 'redux-thunk';
import serialize from 'serialize-javascript';
import jade from 'jade';
export default async (req, res, next, params) => {
// Combining reducers into one parent reducer
const reducer = combineReducers(params.reducers);
// Creating store:
// 1. Applying redux-thunk middleware to perform async actions
// (we can write and apply our own, there can be multiple middlewares here)
// 2. Creating store without reducers
// 3. Adding reducers
const store = applyMiddleware(middleware)(createStore)(reducer);
// Location for router
const location = new Location(req.path, req.query);
// Hosts for api calls and <head> section rendering
const appHost = `${req.protocol}://${req.headers.host}`;
const apiHost = `${req.protocol}://api.${req.headers.host}`;
const { routes } = params;
Router.run(routes, location, async (error, initialState, transition) => {
try {
// Fetching data
await Promise.all(
initialState.components
.filter(component => component.fetchData)
.map(component => component.fetchData({ apiHost, dispatch: store.dispatch }))
);
// Getting the state
const state = store.getState();
let { bundle, locals } = params;
// Rendering <head>
locals.head = React.renderToStaticMarkup(
React.createElement(params.Head, { /* args */ })
);
// Rendering body, notice Provider component
locals.body = React.renderToString(
<Provider store={store}>
{() => <Router location={location} {...initialState} />}
</Provider>
);
const chunks = __DEV__ ? {} : require('public/assets/chunk-manifest.json');
locals.chunks = serialize(chunks);
// Serializing state to expose it on client via global variable
locals.data = serialize(state);
// Compiling Jade template
const layout = `${process.cwd()}/app/bundles/${bundle}/layouts/Layout.jade`;
const html = jade.compileFile(layout, { pretty: false })(locals);
// 😽💨
res.send(html);
} catch (err) {
res.status(500).send(err.stack);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment