Created
November 7, 2017 07:12
-
-
Save velopert/eaf43495de3b2155993ff36a0dc166f1 to your computer and use it in GitHub Desktop.
SSR 참고 자료
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
import React from 'react'; | |
import ReactDOM from 'react-dom'; | |
import Root from './Root'; | |
import registerServiceWorker from './registerServiceWorker'; | |
import routes from './routes'; | |
import { matchPath } from 'react-router'; | |
import 'styles/base.scss'; | |
const render = async () => { | |
// 코드스플리팅된 라우트들을 먼저 불러온 다음에 렌더링 | |
const getComponents = []; | |
routes.forEach( | |
route => { | |
const match = matchPath(window.location.pathname, route); | |
if(!match) return; | |
const { getComponent } = route.component; | |
if(getComponent) { | |
getComponents.push(getComponent()); | |
} | |
} | |
); | |
await Promise.all(getComponents); | |
ReactDOM.hydrate(<Root />, document.getElementById('root')); | |
}; | |
render(); | |
registerServiceWorker(); |
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
import React from 'react'; | |
import PageTemplate from 'components/common/PageTemplate'; | |
import PostContainer from 'containers/post/PostContainer'; | |
import AskRemoveModalContainer from 'containers/modal/AskRemoveModalContainer'; | |
import * as postActions from 'store/modules/post'; | |
const PostPage = ({match}) => { | |
const { id } = match.params; | |
return ( | |
<PageTemplate> | |
<PostContainer id={id}/> | |
<AskRemoveModalContainer id={id}/> | |
</PageTemplate> | |
); | |
}; | |
PostPage.preload = (dispatch, params, query) => { | |
const { id } = params; | |
return dispatch(postActions.getPost(id)); | |
} | |
export default PostPage; |
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
import { ListPage, PostPage, EditorPage } from 'pages'; | |
export default [ | |
{ | |
path: '/', | |
exact: true, | |
component: ListPage | |
}, | |
{ | |
path: '/post/:id', | |
component: PostPage | |
}, | |
{ | |
path: '/page/:page', | |
component: ListPage | |
}, | |
{ | |
path: '/tag/:tag/:page?', | |
component: ListPage | |
}, | |
{ | |
path: '/editor', | |
component: EditorPage | |
} | |
]; |
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
import React from 'react'; | |
import ReactDOMServer from 'react-dom/server'; | |
import { StaticRouter, matchPath } from 'react-router'; | |
import App from 'components/App'; | |
import { Provider } from 'react-redux'; | |
import configure from 'store/configure'; | |
import transit from 'transit-immutable-js'; | |
import { Helmet } from 'react-helmet'; | |
import axios from 'axios'; | |
import routes from './routes'; | |
import queryString from 'query-string'; | |
function parseQuery(url) { | |
return queryString.parse(url.substring(url.indexOf('?') + 1)); | |
} | |
const render = async (url, apiBaseURL) => { | |
if(apiBaseURL) { | |
axios.defaults.baseURL = apiBaseURL; | |
} | |
const store = configure(); | |
const promises = []; | |
// 서브 라우트도 있는 경우를 대비하여 forEach 사용 | |
routes.forEach( | |
route => { | |
const match = matchPath(url, route); | |
if(match) { | |
// redux connect 를 사용한 경우 WrappedComponent 조사 | |
const { component } = route; | |
const { preload } = component; | |
if(!preload) return; | |
const { params } = match; | |
const promise = preload(store.dispatch, params, parseQuery(url)); | |
promises.push(promise); | |
} | |
} | |
); | |
try { | |
await Promise.all(promises); | |
} catch (e) { | |
} | |
const html = ReactDOMServer.renderToString( | |
<Provider store={store}> | |
<StaticRouter location={url}> | |
<App/> | |
</StaticRouter> | |
</Provider> | |
); | |
const helmet = Helmet.renderStatic(); | |
return { | |
helmet, | |
html, | |
preloadedState: JSON.stringify(transit.toJSON(store.getState())).replace(/</g, '\\u003c') | |
}; | |
}; | |
export default render; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment