zoukankan      html  css  js  c++  java
  • react-router之代码分离

    概念

    无需用户下载整个应用之后才能访问访问它。即边访问边下载。因此我们设计一个组件<Bundle>当用户导航到它是来动态加载组件。

    import loadSomething from 'bundle-loader?lazy!./Something'
    
    <Bundle load={loadSomething}>
      {(mod) => (
        // do something w/ the module
      )}
    </Bundle>
    

    如果model是一个component:

    <Bundle load={loadSomething}>
      {(Comp) => (Comp
        ? <Comp/>
        : <Loading/>
      )}
    </Bundle>
    

    这个组件拥有一个load属性(即webpack的 bundle loader)。当组件挂载或者得到一个新的load属性,它将调用load属性,然后放置组件的returned valuestate中,最后在组件的render中回掉该model。源码:

    import React, { Component } from 'react'
    
    class Bundle extends Component {
      state = {
        // short for "module" but that's a keyword in js, so "mod"
        mod: null
      }
    
      componentWillMount() {
        this.load(this.props)
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.load !== this.props.load) {
          this.load(nextProps)
        }
      }
    
      load(props) {
        this.setState({
          mod: null
        })
        props.load((mod) => {
          this.setState({
            // handle both es imports and cjs
            mod: mod.default ? mod.default : mod
          })
        })
      }
    
      render() {
        return this.state.mod ? this.props.children(this.state.mod) : null
      }
    }
    
    export default Bundle
    

    上面render中表明,在model获取之前,render将调用 null state.mod。这样,我们就可以向用户展示一个等待的动画,表明我们正在等待什么东西。

    Why bundle loader, and not import()?

    TC39 最近提出的官方的动态导入是import(),我们可以调整我们的Bundle来使用它:

    <Bundle load={() => import('./something')}>
      {(mod) => ()}
    </Bundle>
    

    bundle loader的最大好处是它第二次同步回调。这样可以在用户每次访问一个代码分离的页面时防止加载页面而造成的页面闪烁。

    忽视你import的方式,思想时一样的:code splitting 即,当组件呈现时用来处理该组件加载的组件。现在你要做的就是在你想要动态加载代码的地方使用<Bundle>

    Loading after rendering is complete

    Bundle component同样也有利于预在后台预加载app的其余部分。

    import loadAbout from 'bundle-loader?lazy!./loadAbout'
    import loadDashboard from 'bundle-loader?lazy!./loadDashboard'
    
    // components load their module for initial visit
    const About = (props) => (
      <Bundle load={loadAbout}>
        {(About) => <About {...props}/>}
      </Bundle>
    )
    
    const Dashboard = (props) => (
      <Bundle load={loadDashboard}>
        {(Dashboard) => <Dashboard {...props}/>}
      </Bundle>
    )
    
    class App extends React.Component {
      componentDidMount() {
        // preloads the rest
        loadAbout(() => {})
        loadDashboard(() => {})
      }
    
      render() {
        return (
          <div>
            <h1>Welcome!</h1>
            <Route path="/about" component={About}/>
            <Route path="/dashboard" component={Dashboard}/>
          </div>
        )
      }
    }
    

    什么时候,多少个你的app要被加载,由你决定。不需要绑定特殊的route。也许你仅仅在用户不活跃的时候,也或许仅仅在用户访问一个route时,或许你想在初始render之后预加载app的其余部分去处理它

    ReactDOM.render(<App/>, preloadTheRestOfTheApp)
    
  • 相关阅读:
    最权威的 Android Oreo 新特性详解
    【送书福利】第一次送书活动(总共10本)
    【资源篇】Python那么火,你还不知道如何人门?
    不忘初心,方得始终 ,让我们一起学习成长,感谢有你!
    搭建环境篇 | 运行第一个Java Web 项目
    为什么我们需要看技术公众号文章?
    手把手教学APK反编译实现源码阅读
    分享一款 Google Pixel 2 独家动态壁纸
    了解CoordinatorLayout,在项目中运用
    jdk 与 jre的区别
  • 原文地址:https://www.cnblogs.com/yaoyinglong/p/7887469.html
Copyright © 2011-2022 走看看