從零開始,構建自己的react項目(二)增加多級路由和按需加載組件


上次剛講完使用webpack從零搭建一個空的React項目,現在接下來開始完善這個架子,增加按需加載的功能和多級路由的功能,關於redux的功能將在下次開始添加。

組件的按需加載

  • 組件按需加載,對於一個比較復雜的頁面來說,是一個不錯的提升頁面加載性能的方法。
  • 首先想到的就是React官方提供的lazy方法,這個lazy有個坑,就是必須要結合Suspense來使用,單獨使用會直接報錯。
  • 由於可能頁面里很多地方都需要使用按需加載,所以講其簡單的封裝抽離成一個公共的按需加載方法。
  • 代碼如下:
    import React, { Suspense, lazy } from 'react';
    
    /**
     * 通用的按需加載組件的方法
     * 使用如下
     *  const HelloWorld = AsyncComponent(() => import('Components/test/HelloWorld'));
     */
    const AsyncComponent = (importFunc) => {
    
      const Component = lazy(importFunc);
    
      return (props) => (
        <Suspense
          fallback={<div>loading...</div>}
        >
          <Component {...props} />
        </Suspense>
      )
    }
    

多級路由的引入

  • 引入路由管理,是針對項目中存在多個不同的,或者多層級的頁面的一種比較好的解決方法,沒有路由也不是不可以做,就是管理起來不是很方便。
  • 要注意一下,當react-router升級到4.0以后就不再支持Route的多級嵌套了,所以每次存在子路由的時候,可能需要一個公共的父級頁面來專門渲染子路由。
  • 首先是在routes文件夾下添加對應的路由配置文件。
    import { AsyncComponent } from 'Utils/component';
    
    const Main = AsyncComponent(() => import('Pages/main'));
    const Home = AsyncComponent(() => import('Pages/Home'));
    const HelloWorld = AsyncComponent(() => import('Components/test/HelloWorld'));
    
    const routes = [
      {
        path: '/',
        component: Main,
        exact: true // 嚴格匹配,保證剛進來的時候直接展示首頁
      },
      {
        path: '/',
        component: Home, // 模糊匹配,進入子路由的時候,就會走這里
        children: [
          {
            path: '/hello',
            component: HelloWorld
          }
        ]
      }
    ];
    
    export default routes;
    
  • 然后是多路由的渲染,我將其抽離出來,方便后續可以增加功能,比如可以將全局的search參數做處理后傳入路由對應的組件,方便使用
    /**
    * 路由遍歷功能
    */
    const renderRoutes = (routes) => {
    
      return routes.map((route, index) => {
        const { children, path, exact = false } = route;
        /**
          * 可以在這里做一些全局的處理,把search參數處理之后傳進route.component,這樣就不用每個頁面都要對search參數去做一次處理
          */
        const search = location.search;
        const query = searchToQuery(search); // 將search字符串變成一個對象,然后傳入 
        return (
          <Route
            path={path}
            exact={exact}
            key={`${route.path}-${index}`}
            render={props => <route.component {...props} routes={children} urlQuery={query} />}
          />
        )
      })
    }
    
  • 在入口文件index.js中使用路由。
    import React from "react";
    import ReactDOM from "react-dom";
    import { Router } from 'react-router';
    import { createBrowserHistory } from 'history';
    
    import { renderRoutes } from 'Utils/component';
    import routes from 'Routes';
    
    const browserHistory = createBrowserHistory(); 
    // 使用browserHistory有一個注意點,本地開發時,需要將webpack的config.devServer.historyApiFallback設置為true。不然會出現你輸入路徑時,把路徑當做接口來訪問,而不是當做路由。
    
    function render() {
      ReactDOM.render(
        <Router history={browserHistory}>
          {
            renderRoutes(routes)
          }
        </Router>,
        document.getElementById("root")
      );
    }
    
    render();
    
  • 至此,我們的異步加載組件和多級路由全部加入,下一次就是配置redux。

小結

  • 到目前為止,這個架子已經可以滿足一些小型的業務需求,如果對於龐大的業務量,最好還是把redux的狀態管理給加上,不然全局狀態會很亂。
  • 源碼路徑,https://github.com/810307015/ReactDemo,有興趣可以看看。
  • 看到這里的小伙伴們,給我點個贊,留個言啊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM