Skip to content

Instantly share code, notes, and snippets.

@tadjik1
Created August 15, 2015 20:14
Show Gist options
  • Save tadjik1/40b2f31c6a7996052fde to your computer and use it in GitHub Desktop.
Save tadjik1/40b2f31c6a7996052fde to your computer and use it in GitHub Desktop.
server rendering redux
import 'babel/polyfill';
import 'isomorphic-fetch';
import koa from 'koa';
import favicon from 'koa-favicon';
import serve from 'koa-static';
import logger from 'koa-logger';
import fs from 'fs';
import path from 'path';
import _ from 'lodash';
import React from 'react';
import Router from 'react-router';
import { Provider } from 'react-redux';
import DocumentTitle from 'react-document-title';
import routes from '../shared/routes';
import createStore from '../shared/store';
const templateFile = path.join(__dirname, 'views/index.html');
const template = _.template(fs.readFileSync(templateFile, 'utf8'));
const app = koa();
const port = process.env.PORT || 5000;
app.use(logger());
app.use(favicon(path.join(__dirname, 'public/favicon.ico')));
app.use(serve(path.join(__dirname, 'public')));
const getComponentActions = (component={}) => {
return component.WrappedComponent ?
getComponentActions(component.WrappedComponent) :
component.willRender;
};
app.use(function* errorHandler(next) {
try {
yield next;
} catch (err) {
this.status = err.status || 500;
this.body = err.message;
this.app.emit('error', err, this);
}
});
app.use(function* appHandler() {
const store = createStore();
const router = Router.create({
routes: routes,
location: this.url,
onError: error => {
throw error;
},
onAbort: abortReason => {
throw new Error(abortReason);
}
});
let html;
const { Handler, state } = yield new Promise((resolve) => {
router.run((_Handler, _state) => {
resolve({ Handler: _Handler, state: _state });
});
});
try {
yield state.routes.map((route) => {
// call willRender on all routes to get async data
return getComponentActions(route.handler) && getComponentActions(route.handler)(store);
}).filter(Boolean);
} catch (error) {
console.warn(error); // eslint-disable-line no-console
}
html = React.renderToString(
<Provider store={store}>
{() => <Handler {...state} />}
</Provider>
);
this.body = template({
title: DocumentTitle.rewind(),
body: html,
state: JSON.stringify(store.getState())
});
});
app.listen(port, () => {
if (process.send) {
process.send('online');
} else {
console.log(`The server is running at http://127.0.0.1:${port}`); // eslint-disable-line no-console
}
});
@tadjik1
Copy link
Author

tadjik1 commented Aug 15, 2015

all of my actions created with call-api-middleware from one examples in docs:

export default function callAPIMiddleware({ dispatch, getState }) {
    return (next) => {
        return (action) => {
            const {
                types,
                callAPI,
                shouldCallAPI = () => true,
                payload = {}
            } = action;

            if (!types) {
                // Normal action: pass it on
                return next(action);
            }

            if (
                !Array.isArray(types) ||
                types.length !== 3 || !types.every(type => typeof type === 'string')
            ) {
                throw new Error('Expected an array of three string types.');
            }

            if (typeof callAPI !== 'function') {
                throw new Error('Expected fetch to be a function.');
            }

            if (!shouldCallAPI(getState())) {
                return; // eslint-disable-line consistent-return
            }

            const [requestType, successType, failureType] = types;

            dispatch(Object.assign({}, payload, {
                type: requestType
            }));

            return callAPI().then(
                response => dispatch(Object.assign({}, payload, {
                    payload: response,
                    type: successType
                })),
                error => dispatch(Object.assign({}, payload, {
                    error: error,
                    type: failureType
                }))
            );
        };
    };
}

So all of them returns promise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment