Last active
May 12, 2017 02:22
-
-
Save panacholn/44e9af99ad93a4d43b42473c9c658bb2 to your computer and use it in GitHub Desktop.
SSR Workshop
This file contains hidden or 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
Part 1 : Config Server | |
// ไฟล์ src/server/server.js | |
1. import ไฟล์ตามนี้ | |
const createMemoryHistory = require('react-router/lib/createMemoryHistory'); | |
const configureStore = require('../common/stores').default; | |
const { syncHistoryWithStore } = require('react-router-redux'); | |
const { RouterContext, match } = require('react-router'); | |
const routes = require('../common/routes').default; | |
const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup; | |
const { Provider } = require('react-redux'); | |
const React = require('react'); | |
2. สร้าง function สำหรับ render html template | |
const renderHTML = renderedComponent => (` | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<link rel="stylesheet" href="https://bootswatch.com/flatly/bootstrap.min.css"> | |
<link rel="stylesheet" type="text/css" href="/dist/styles.css" /> | |
</head> | |
<body> | |
<div id="root">${renderedComponent}</div> | |
</body> | |
<script src="/dist/bundle.js"></script> | |
</html> | |
`); | |
3. แก้ใน app.get ให้เป็น | |
const memoryHistory = createMemoryHistory(req.originalUrl); | |
const store = configureStore(memoryHistory); | |
const history = syncHistoryWithStore(memoryHistory, store); | |
match({ | |
location: req.originalUrl, | |
routes: routes(store, history), | |
}, (error, redirectLocation, renderProps) => { | |
if (error) { | |
res.status(500).send(error.message); | |
} else if (redirectLocation) { | |
res.redirect(302, `${redirectLocation.pathname}${redirectLocation.search}`); | |
} else if (renderProps) { | |
const renderedComponent = renderToStaticMarkup( | |
<Provider store={store} key="provider"> | |
<RouterContext {...renderProps} /> | |
</Provider>, | |
); | |
res.status(200).send(renderHTML(renderedComponent)); | |
} else { | |
res.status(404).send('Not Found'); | |
} | |
}); |
This file contains hidden or 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
Part 2 : Babel / CSS | |
// ไฟล์ src/server/index.js | |
1. เพิ่ม babel-register กับ css-modules-require-hook | |
require('babel-register'); | |
const hook = require('css-modules-require-hook'); | |
hook({ extensions: '.scss' }); |
This file contains hidden or 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
Part 3 : Prefetch Data | |
// ไฟล์ src/common/containers/CommentList.js | |
1. เพิ่มโค้ดตามนี้ | |
CommentList.prefetchAction = [ | |
() => getList(), | |
]; | |
// สร้างไฟล์ src/server/prefetchData.js | |
2. เพิ่มโค้ดตามนี้ | |
export default function prefetchData(dispatch, components, renderProps) { | |
const prefetchActions = components | |
.filter(component => component) | |
.reduce((prev, current) => { | |
const wrappedComponent = current.WrappedComponent; | |
return (current.prefetchAction || []) | |
.concat((wrappedComponent && wrappedComponent.prefetchAction) || []) | |
.concat(prev); | |
}, []); | |
return Promise.all([...new Set(prefetchActions)].map(prefetchAction => dispatch(prefetchAction(renderProps)))); | |
} | |
// ไฟล์ src/server/server.js | |
3. เพิ่ม import ไฟล์ | |
const prefetchData = require('./prefetchData').default; | |
4. แก้ใน else if (renderProps) | |
const { components } = renderProps; | |
prefetchData(store.dispatch, components, renderProps) | |
.then(() => { | |
const renderedComponent = renderToStaticMarkup( | |
<Provider store={store} key="provider"> | |
<RouterContext {...renderProps} /> | |
</Provider>, | |
); | |
res.status(200).send(renderHTML(renderedComponent)); | |
}); |
This file contains hidden or 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
Part 4 : Remove Duplicate Request | |
// ไฟล์ src/server/server.js | |
1. แก้โค้ด function renderHTML ให้รับ preloadState | |
const renderHTML = (renderedComponent, preloadState) | |
2. เพิ่ม preloadState ใน HTML template | |
<script>window.preloadState = ${JSON.stringify(preloadState)}</script> | |
<script src="/dist/bundle.js"></script> | |
3. ส่ง state เข้า function renderHTML | |
res.status(200).send(renderHTML(renderedComponent, store.getState())); | |
// ไฟล์ src/client/index.js | |
4. แก้โค้ดให้รับ state จาก HTML และ set เข้า store | |
const preloadState = window.preloadState || {}; | |
const Store = store(browserHistory, preloadState); | |
// ไฟล์ src/common/containers/CommentList.js | |
5. แก้ให้ function เช็คว่ามีข้อมูลรึเปล่าก่อนจะ fetch ข้อมูล | |
componentDidMount() { | |
if (this.props.list.length === 0) { | |
this.props.onGetList(); | |
} | |
} | |
part2: ข้อ 3 ที่รับ parameter preload state ใน store ไม่ต้องแก้ละ เพิ่มไปใน step 0 แล้ว
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
part1:
const createMemoryHistory = require('react-router/lib/createMemoryHistory');
const configureStore = require('../common/stores').default;
const { syncHistoryWithStore } = require('react-router-redux');
const { RouterContext, match } = require('react-router');
const routes = require('../common/routes').default;
const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup;
const { Provider } = require('react-redux');
const React = require('react');