React服务端渲染原理
由于React是通过动态Dom树进行HTML的绘制,并且是数据驱动视图的,所以在SEO的搜索中,动态Dom树的填充内容不会被搜索到。当网页需要提高搜索量,或者进行某些兼容性处理时,就需要将动态的Dom树转换为字符串的形式以静态资源进行加载,兼容性的处理也是通过对静态资源根据浏览器不通特性,通过Hack等规则替换进行实现。(刚查看了资料,可以将字符串的Dom转换为XML进行替换:使用工具:var xmlDoc = new ActiveXObject(/"Microsoft.XMLDOM/");)。
服务端渲染的实现,是通过开启nodejs服务监听,将已经渲染好的Dom页面加载到浏览器端进行展现;
当使用服务器端渲染时,如果需要使用Redux,则将store赋值给Provider在Router中进行store的传递;
import { StaticRouter, RouterContext } from 'react-router';
import { Provider } from 'react-redux';
<Provider store={finalState}>
<StaticRouter location={req.url} context={context}>
{getRoutes()}
</StaticRouter>
</Provider>
当需要使用Router中 history时,需要将组件包裹在 withRouter 中
import { withRouter } from 'react-router';
export default connect(mapStateToProps,mapDispatchToProps)(withRouter(AgencyEvent));
当nodejs服务监听到访问请求时,通过${}EL 表达式,将绘制好的Dom页面以字符串的形式写入到html模版中,使用response渲染到浏览器端进行展示。此时渲染出的html页面是没有携带事件机制的。所以此时需要再次在客户端进行渲染,使得DOM树的节点可以触发。
React服务端渲染实现
import { renderToString } from 'react-dom/server';
const markup = renderToString(
<Provider store={finalState}>
<StaticRouter location={req.url} context={context}>
{getRoutes()}
</StaticRouter>
</Provider>
);
const html = renderPage (markup, {});
res.status(200).send(html);
function renderPage (html, initialState) {
return `
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>服务端渲染页面</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root">${html}</div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}
</script>
<script type="text/javascript" src="/static/bundle.js" defer></script>
</body>
</html>`;
如果模版不需要进行特别处理,也可以使用webpack自动生产的html文件进行渲染
参考地址:
https://reacttraining.com/react-router/web/guides/server-rendering
https://redux.js.org/recipes/server-rendering
网友评论