美文网首页
react-router 实现传统路由异步加载

react-router 实现传统路由异步加载

作者: potato_2bbf | 来源:发表于2021-01-04 12:03 被阅读0次

手动配置路由的时候,也许路由会这样配置

<Switch>
  <Route path={'/index'} component={Index}></Route>
  <Route path={'/list'} component={List}></Route>
  <Route path={'/detail'} component={Detail}></Route>
  <Redirect from='/*' to='/index' />
</Switch>

或者用数组,方便拦截,或者配置

const router = [
  {
    path: '/index',
    component: Index
  },
  {
    path: '/list',
    component: List
  },
  {
    path: '/detail',
    component: Detail
  }
]

asyncRouter懒加载路由,并实现路由监听

/* 存放路由钩子 */
const routerObserveQueue = [] 

/* 懒加载路由钩子 */
export const RouterHooks = {
  /* 路由组件加载之前 */
  beforeRouterComponentLoad: function (callback) {
    routerObserveQueue.push({
      type: 'before',
      callback
    })
  },
  /* 路由组件加载之后 */
  afterRouterComponentDidLoaded(callback) {
    routerObserveQueue.push({
      type: 'after',
      callback
    })
  }
}

/* 路由懒加载HOC */
export default function AsyncRouter(loadRouter) {
  return class Content extends React.Component {
    constructor(props) {
      super(props)
      /* 触发每个路由加载之前钩子函数 */
      this.dispatchRouterQueue('before')
    }
    state = { Component: null }
    dispatchRouterQueue(type) {
      const { history } = this.props
      routerObserveQueue.forEach(item => {
        if (item.type === type) item.callback(history)
      })
    }
    componentDidMount() {
      if (this.state.Component) return
      loadRouter()
        .then(module => module.default)
        .then(Component =>
          this.setState({ Component }, () => {
            /* 触发每个路由加载之后钩子函数 */
            this.dispatchRouterQueue('after')
          })
        )
    }
    render() {
      const { Component } = this.state
      return Component ? <Component {...this.props} /> : null
    }
  }
}

asyncRouter实际就是一个高级组件,将()=>import()作为加载函数传进来,然后当外部Route加载当前组件的时候,在componentDidMount生命周期函数,加载真实的组件,并渲染组件,我们还可以写针对路由懒加载状态定制属于自己的路由监听器beforeRouterComponentLoad和afterRouterComponentDidLoaded,类似vue中 watch $route 功能。接下来我们看看如何使用。

使用

import AsyncRouter, { RouterHooks } from './asyncRouter.js'
const { beforeRouterComponentLoad } = RouterHooks
const Index = AsyncRouter(() => import('../src/page/home/index'))
const List = AsyncRouter(() => import('../src/page/list'))
const Detail = AsyncRouter(() => import('../src/page/detail'))

const index = () => {
  useEffect(() => {
    /* 增加监听函数 */
    beforeRouterComponentLoad(history => {
      console.log('当前激活的路由是', history.location.pathname)
    })
  }, [])
  return (
    <div>
      <div>
        <Router>
          <Meuns />
          <Switch>
            <Route path={'/index'} component={Index}></Route>
            <Route path={'/list'} component={List}></Route>
            <Route path={'/detail'} component={Detail}></Route>
            <Redirect from='/*' to='/index' />
          </Switch>
        </Router>
      </div>
    </div>
  )
}

这样一来,我们既做到了路由的懒加载,又弥补了react-router没有监听当前路由变化的监听函数的缺陷。

摘自https://juejin.cn/post/6908895801116721160

相关文章

网友评论

      本文标题:react-router 实现传统路由异步加载

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