Skip to content

Commit

Permalink
A bare minimum Redux integration
Browse files Browse the repository at this point in the history
  • Loading branch information
koistya committed Sep 27, 2016
1 parent fd2845f commit 6149ef2
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 1 deletion.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
"query-string": "4.2.3",
"react": "15.3.2",
"react-dom": "15.3.2",
"react-redux": "4.4.5",
"redux": "3.6.0",
"sequelize": "3.24.3",
"serialize-javascript": "1.3.0",
"source-map-support": "0.4.2",
"sqlite3": "3.1.4",
"universal-router": "1.2.2",
Expand Down
4 changes: 4 additions & 0 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import queryString from 'query-string';
import createBrowserHistory from 'history/createBrowserHistory';
import { createPath } from 'history/PathUtils';
import App from './components/App';
import createStore from './core/createStore';

// Global (context) variables that can be easily accessed from any React component
// https://facebook.github.io/react/docs/context.html
Expand All @@ -30,6 +31,9 @@ const context = {
const removeCss = styles.map(x => x._insertCss());
return () => { removeCss.forEach(f => f()); };
},
// Initialize a new Redux store
// http://redux.js.org/docs/basics/UsageWithReact.html
store: createStore(window.APP_STATE),
};

function updateTag(tagName, keyName, keyValue, attrName, attrValue) {
Expand Down
7 changes: 7 additions & 0 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ const ContextType = {
// Enables critical path CSS rendering
// https://github.com/kriasoft/isomorphic-style-loader
insertCss: PropTypes.func.isRequired,
// Integrate Redux
// http://redux.js.org/docs/basics/UsageWithReact.html
store: PropTypes.shape({
subscribe: PropTypes.func.isRequired,
dispatch: PropTypes.func.isRequired,
getState: PropTypes.func.isRequired,
}).isRequired,
};

/**
Expand Down
7 changes: 6 additions & 1 deletion src/components/Html.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
*/

import React, { PropTypes } from 'react';
import serialize from 'serialize-javascript';
import { analytics } from '../config';

function Html({ title, description, style, script, children }) {
function Html({ title, description, style, script, state, children }) {
return (
<html className="no-js" lang="en">
<head>
Expand All @@ -24,6 +25,9 @@ function Html({ title, description, style, script, children }) {
</head>
<body>
<div id="app" dangerouslySetInnerHTML={{ __html: children }} />
<script
dangerouslySetInnerHTML={{ __html: `window.APP_STATE=${serialize(state || {})}` }}
/>
{script && <script src={script} />}
{analytics.google.trackingId &&
<script
Expand All @@ -45,6 +49,7 @@ Html.propTypes = {
description: PropTypes.string.isRequired,
style: PropTypes.string,
script: PropTypes.string,
state: PropTypes.object,
children: PropTypes.string,
};

Expand Down
16 changes: 16 additions & 0 deletions src/core/createStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* React Starter Kit (https://www.reactstarterkit.com/)
*
* Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/

import { createStore, combineReducers } from 'redux';

const reducers = {
// TODO: Place your application store reducers here
};

export default createStore.bind(undefined, combineReducers(reducers));
7 changes: 7 additions & 0 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import models from './data/models';
import schema from './data/schema';
import routes from './routes';
import assets from './assets'; // eslint-disable-line import/no-unresolved
import createStore from './core/createStore';
import { port, auth } from './config';

const app = express();
Expand Down Expand Up @@ -102,6 +103,11 @@ app.get('*', async (req, res, next) => {
// eslint-disable-next-line no-underscore-dangle
styles.forEach(style => css.add(style._getCss()));
},
// Initialize a new Redux store
// http://redux.js.org/docs/basics/UsageWithReact.html
store: createStore({
user: req.user || null,
}),
};

const route = await UniversalRouter.resolve(routes, {
Expand All @@ -113,6 +119,7 @@ app.get('*', async (req, res, next) => {
data.children = ReactDOM.renderToString(<App context={context}>{route.component}</App>);
data.style = [...css].join('');
data.script = assets.main.js;
data.state = context.store.getState();
const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);

res.status(route.status || 200);
Expand Down

0 comments on commit 6149ef2

Please sign in to comment.