import { renderToString } from 'react-dom/server' import { Provider } from 'react-redux' import { createStore } from 'redux' import App from './App' import rootReducer from './reducers' const store = createStore(rootReducer) async function(ctx) { await ctx.render('index', { root: renderToString( <Provider store={store}> <App /> </Provider> ), state: store.getState() }) }
详解React 服务端渲染方案完美的解决方案(4)
HTML
<body> <div id="root"><%- root %></div> <script> window.REDUX_STATE = <%- JSON.stringify(state) %> </script> </body>
客户端
import { render } from 'react-dom' import { Provider } from 'react-redux' import { createStore } from 'redux' import App from './App' import rootReducer from './reducers' const store = createStore(rootReducer, window.REDUX_STATE) render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
路由方案
客户端路由的好处就不必多说了,客户端可以不依赖服务端,根据hash方式或者调用history API,不同的URL渲染不同的视图,实现无缝的页面切换,用户体验极佳。但服务端渲染不同的地方在于,在渲染之前,必须根据URL正确找到相匹配的组件返回给客户端。
React Router为服务端渲染提供了两个API:
- - match 在渲染之前根据URL匹配路由组件
- - RoutingContext 以同步的方式渲染路由组件
服务端
import { renderToString } from 'react-dom/server' import { Provider } from 'react-redux' import { createStore } from 'redux' import { match, RouterContext } from 'react-router' import rootReducer from './reducers' import routes from './routes' const store = createStore(rootReducer) async function clientRoute(ctx, next) { let _renderProps match({routes, location: ctx.url}, (error, redirectLocation, renderProps) => { _renderProps = renderProps }) if (_renderProps) { await ctx.render('index', { root: renderToString( <Provider store={store}> <RouterContext {..._renderProps} /> </Provider> ), state: store.getState() }) } else { await next() } }
客户端
import { Route, IndexRoute } from 'react-router' import Common from './Common' import Home from './Home' import Explore from './Explore' import About from './About' const routes = ( <Route path="/" component={Common}> <IndexRoute component={Home} /> <Route path="explore" component={Explore} /> <Route path="about" component={About} /> </Route> ) export default routes
内容版权声明:除非注明,否则皆为本站原创文章。