Last active
November 12, 2018 16:29
-
-
Save wzup/702af49d7e386d845c56c76fc3a5b1b1 to your computer and use it in GitHub Desktop.
React server-side rendering with react-router 3.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const NODE_ENV = process.env.NODE_ENV || 'development'; | |
/* React and Redux stuff */ | |
const React = require('react'); | |
const ReactDOM = require('react-dom'); | |
import { Provider } from 'react-redux'; | |
import { createStore, applyMiddleware, combineReducers, compose } from 'redux'; | |
import thunkMiddleware from 'redux-thunk'; | |
import { routerMiddleware, routerReducer } from 'react-router-redux'; | |
import createHistory from 'history/createBrowserHistory'; | |
const history = createHistory(); | |
import { createLogger } from 'redux-logger'; | |
const loggerMiddleware = createLogger(); | |
const middleware = routerMiddleware(history); | |
/** | |
* My four modules. | |
*/ | |
const reducersFactory = require('./reducersFactory'); | |
const GetRouter = require('./router'); | |
let getRoutes = require('./routes'); | |
let state = require('./state'); | |
/** | |
* <BrowserRouter> props. In separate variable for convenience | |
* https://reacttraining.com/react-router/web/api/BrowserRouter | |
*/ | |
let routerConf = { | |
basename: '/', // string | |
getUserConfirmation: null, // func | |
forceRefresh: false, // bool, full reload or not | |
keyLength: 12, // num, def == 6, | |
} | |
/** | |
* This is for redux-devtools-extension in Chrome console. | |
* Just a useful dev feature. It has nothing to do with my app. | |
* https://github.com/zalmoxisus/redux-devtools-extension | |
*/ | |
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; | |
/** | |
* Create Redux store. | |
* http://redux.js.org/docs/basics/Store.html | |
* http://redux.js.org/docs/api/createStore.html | |
*/ | |
let store = createStore( | |
reducersFactory({}), // pass initial state. | |
window.__state__, // important. | |
// applyMiddleware(thunkMiddleware, loggerMiddleware, middleware), // if w/o redux-devtools-extension | |
composeEnhancers( applyMiddleware(thunkMiddleware, loggerMiddleware, middleware) ) // if with redux-devtools-extension | |
); | |
/** | |
* Assemble a final app component. To render it into a DOM node. | |
*/ | |
let Application = ( | |
<Provider store={store}> | |
<GetRouter env="browser" routes={getRoutes({})} routerConf={routerConf} /> | |
</Provider> | |
) | |
/** | |
* Finally, render it into DOM node | |
*/ | |
ReactDOM.render(Application, document.getElementById('root')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* I make reducersFactory a function in order to pass it an initial state as a parameter. | |
* Switch-case are just for example. You may have your own | |
*/ | |
function reducersFactory(initialState) { | |
return function reducers(state = initialState, action) { | |
switch (action.type) { | |
case 'login_success': | |
return Object.assign({}, state, { | |
user: action.user, | |
login_starts: false, | |
}); | |
break; | |
case 'login_failure': | |
return Object.assign({}, state, { | |
user: action.user, | |
login_starts: false, | |
}); | |
break; | |
default: | |
return state; | |
} | |
} | |
} | |
module.exports = reducersFactory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const NODE_ENV = process.env.NODE_ENV || 'development'; | |
const React = require('react'); | |
import { StaticRouter, BrowserRouter, Route, Link } from 'react-router-dom'; | |
import { ConnectedRouter } from 'react-router-redux'; | |
/** | |
* This is only Router. | |
* This is how I separate it for browser and server environment | |
* Look at browser.js and server.js and you will see how env prop is passed here | |
*/ | |
function getRouter(params) { | |
if(params.env == 'browser') { | |
return ( | |
<BrowserRouter router={params.routerConf}> | |
{params.routes} | |
</BrowserRouter> | |
); | |
} | |
if(params.env == 'server') { | |
return ( | |
<StaticRouter | |
basename='/' | |
location={params.url} | |
context={params.context}> | |
{params.routes} | |
</StaticRouter> | |
) | |
} | |
} | |
module.exports = getRouter; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment