服务端初始化Redux的必要性
- SSR为了解决首屏渲染时间和SEO的问题,那么首屏的内容怎么办?
- 服务端请求完首屏数据后,客户端接管后是否又重新去请求首屏数据
- 为了解决以上问题所以服务端加载首屏数据并初始化到状态树非常必要
服务端加载首屏数据
// 1. 服务端拿到首屏数据放入状态树
app.get( "/*", async ( req, res ) => {
try {
let modules = [];
const context = {};
const store = createServerStore();
const { dispatch } = store;
const result = await fetchUserMsg('binyellow'); // 请求完首屏需要的数据
dispatch(initializeUserMsg(result.data)); // 将首屏数据传入状态树
const jsx = (
<Provider store={store}>
<Loadable.Capture report={moduleName => modules.push(moduleName)}>
<StaticRouter context={ context } location={ req.url }>
<Layout />
</StaticRouter>
</Loadable.Capture>
</Provider>
);
const reactDom = renderToStaticMarkup( jsx );
let bundles = getBundles(stats, modules);
const state = store.getState();
res.writeHead( 200, { "Content-Type": "text/html" } );
res.end( htmlTemplate( reactDom, bundles, state ) );
} catch (error) {
throw error;
}
});
// 2.将JSON数据挂载到window的特殊key上
<script>
window.REDUX_DATA = ${ JSON.stringify( state ) }
window.env = 'server'
</script>
客户端
// 1. 将window上的JSON数据初始化到Store中
const store = createClientStore( window.REDUX_DATA );
const jsx = (
<Provider store={store}>
<Router>
<Layout />
</Router>
</Provider>
);
要考虑的问题
- 服务端请求数据可能造成用户等待时间,所以要简化请求数据
- 客户端要判断develop状态下(调试页面),或者服务端请求出错的情况下,去加载首屏数据