SSR结合React-Router

作者: binyellow | 来源:发表于2019-04-21 17:28 被阅读21次

服务端根据请求url来返回对应的页面

  1. StaticRouter支持服务端渲染的路由,它的位置一直不变,只是根据请求的url来定位location并渲染对一个的组件
  2.  <StaticRouter context={ context } location={ req.url }>
       <Layout />
     </StaticRouter>
    

服务端返回格式好的html后

  1. 加载客户端的代码,加载好事件绑定后
  2. 客户端接管路由跳转和ajax请求
  3.  const jsx = (
       <Router>
         <Layout />
       </Router>
     );
     ReactDOM.hydrate( jsx, app );
    

配合react-loadable实现代码分割和懒加载

公共路由文件

const Home = Loadable({
  loader: ()=> import(/* webpackChunkName: 'Home' */'./Home'),
  loading,
});
const Hello = Loadable({
  loader: ()=> import(/* webpackChunkName: 'Hello' */'./Hello'),
  loading,
});
export default class Layout extends React.Component {
  constructor() {
    super();
    this.state = {
      title: "Welcome to React SSR!"
    };
  }
  render() {
    return (
      <div>
        <h1>{this.state.title}</h1>
        <div>
          <Link to="/">Home</Link>
          <Link to="/hello">Hello</Link>
        </div>
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/hello" exact component={Hello} />
        </Switch>
      </div>
    );
  }
}

客户端

const jsx = (
    <Provider store={store}>
      <Router>
        <Layout />
      </Router>
    </Provider>
);

const app = document.getElementById( "app" );
Loadable.preloadReady().then(() => {  // 懒加载依赖准备好了,然后去渲染并为dom元素添加事件
  ReactDOM.hydrate( jsx, app );
});

服务端

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 ); // 不会创建额外的Dom属性
let bundles = getBundles(stats, modules); // 依赖的bundle
const state = store.getState();
htmlTemplate( reactDom, bundles, state )

Loadable.preloadAll().then(() => {
  app.listen(3000, () => {
    console.log('Running on http://localhost:3000/');
  });
});

按需加载实现原理

  1. 在webpack中可以通过require.ensureimport()来实现
  2. react-lodable高阶组件实现原理
  Lodable({
    loader: ()=> import(/* webpackChunkName: 'Hello' */'./Hello'),
    loading,
  })
  class Lodable {
    componentWillMount() {
      this.cancelUpdate = false;
      const { loader } = this.props;
      loader.then(Com=> {
        this.Com = Com;
        if(!this.cancelUpdate) {
          thi.forceUpdate(); // 初次懒加载完后重新渲染
        }
      })
    }
    componentWillUnmount() {
      this.cancelUpdate = true;
    }
    render() {
      const { comProps } = this.props;
      return this.Com ? (
        <this.Com.default {...comProps} />
      ) : (
        <this.Com {...comProps}/>
      )
    }
  }

相关文章

  • SSR结合React-Router

    服务端根据请求url来返回对应的页面 StaticRouter支持服务端渲染的路由,它的位置一直不变,只是根据请求...

  • SSR结合Redux

    服务端初始化Redux的必要性 SSR为了解决首屏渲染时间和SEO的问题,那么首屏的内容怎么办? 服务端请求完首屏...

  • SSR介绍-2: 传统SSR实现

    此篇文章将结合vue来简单介绍如何实现传统的SSR,为后续实现现今流行的SSR打个基础。参考vue ssr官网:h...

  • react之手动实现ssr跟next的区别

    react ssr框架next.js具体文档:next文档; 自己手动结合react+node实现一个ssr需求:...

  • Could not find router reducer in

    问题描述 再添加connect-react-router依赖后使用redux结合react-router进行路由跳...

  • React SSR样式及SEO的实践

    前一篇主要记录了一下SSR配置以及结合Redux的使用。这里简单说一下React SSR中样式处理和更优雅的SEO...

  • react-router和PureComponent

    react-router react-router包含3个库,react-router、react-router-...

  • Linux 配置代理

    软件要求 SSR Proxychains4 准备工作 SSR 获取ssr脚本 赋予ssr脚本可执行权限 将ssr放...

  • VUE SSR

    VUE SSR 官方文档: Vue SSR 指南 一、什么是SSR, 为什么要做SSR 什么是SSRVue.js ...

  • 详解Vue SSR服务端渲染

    Vue SSR介绍[https://ssr.vuejs.org/zh/] SSR Github Demo[http...

网友评论

    本文标题:SSR结合React-Router

    本文链接:https://www.haomeiwen.com/subject/caejgqtx.html