<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          我?guī)鸵慌笥阎貥嬃它c代碼,他直呼牛批,但基操勿六

          共 5546字,需瀏覽 12分鐘

           ·

          2022-05-17 12:46

          點擊上方?前端Q,關注公眾號

          回復加群,加入前端Q技術交流群


          首先事情是這樣的

          我一朋友,用 react 開發(fā)前端時間不長,一些簡單的功能和頁面沒啥大問題。前不久React 18 發(fā)布了,他就用 create-react-app 創(chuàng)建了一個新項目,合計練練手,但誰成想遇到了種種問題,讓我?guī)涂纯矗谑蔷陀辛私酉聛硪牡囊恍┛此坪唵危菍π率謪s很絆腳的小問題。

          react都 18 了,但為啥還是 ReactDom.render

          create-react-app新創(chuàng)建的項目,還是用的ReactDom.render,如下:

          import?React?from?'react'
          import?ReactDOM?from?'react-dom'?//《----------react?17使用的ReactDOM
          import?App?from?'./App'
          import?'./index.css'

          ReactDOM.render(
          ??
          ????
          ??</React.StrictMode>,
          ??document.getElementById('root')
          )
          復制代碼

          語義大體上:ReactDOMrender 函數(shù),把 JSX Elements 組件,渲染到 id 為'root'的 dom 節(jié)點上。

          那么用react 18的新寫法改造一下

          react 18改了

          //index.tsx
          import React from 'react'
          import { createRoot } from 'react-dom/client' //《----------react 18使用的ReactDOM/client中的createRoot
          import App from './App'
          import './index.css'

          function render() {
          const root = createRoot(document.getElementById('root')!)
          root.render(



          )
          }
          復制代碼

          語義大體上:react-dom/clientcreateRoot 函數(shù),把 id 為'root'的 dom 節(jié)點做成了一個渲染器,然后用Render函數(shù)把JSX Elements渲染出來。

          react 都 18 了,React-router 得 v6 啊,但變化好大,咋用啊?

          React-router v6可謂是變化著實不小,之前v5組織路由是這樣的:

          React-router v5

          //app.tsx
          import React from 'react'
          import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
          export default () => {
          return (






          )
          }
          )
          復制代碼

          PageCenter就是我們的頁面組件,一般都會在這里實現(xiàn)嵌套路由,如:

          //PageCenter.tsx
          import React from 'react'
          import NestRoute from ‘./nestRoute’
          import { Route, Switch } from "react-router-dom";
          export default () => {
          return (
          <>



          <>
          )
          }
          )
          復制代碼

          em ~~~,跟 app.tsx 中實現(xiàn)的頂層路由很像,一脈相承。

          評價一波 v5 路由的組織方式吧

          • tsx 文件大臃腫:每配置一個路由,就寫一個 Route 組件,我個人是不喜歡的,我不希望我的 tsx 的代碼太多,這是我的喜好,為了閱讀起來容易,清晰。
          • 項目的文件夾結構復雜嵌套:頂層路由和嵌套子路由配置分離,直接影響了工程項目中對項目的文件夾結構的編排。因為不能夠很直接理清頁面組件間的組織關系,不理清會很混亂,維護難度加大,所以理清關系就落在了項目的文件夾結構設計了,這就會導致項目的文件夾結構隨著v5 路由的組織方式的復雜而復雜。

          React-router v6

          可能是因為 v5 的種種原因,才導致 v6 的變化那么大,最突出便是:

          • v6 痛快的推出了配置式路由:一個簡單的配置對象,充分描述出了路由的樣子和組織關系,痛快~~~。
          • 簡潔的路由嵌套方式:僅僅在配置了嵌套路由組件中,使用新推出的標簽就搞定了,優(yōu)雅~~~。

          不過~~~,也有一些破壞性的改變,讓我措手不及,比如:

          • 路由攔截無了!!!:攔截啊可是,怎么沒有了,這。。。
          • withRouter無了!!!:函數(shù)組件我能用hook搞搞,類組件咋辦,這。。。

          em ~~~沒事 repect,畢竟進步嘛,怎么會沒代價呢,沒有咱就自己搞被,不坐車就不會走了么?

          我為此寫了一個庫r6helper[2],盡可能的彌補了升級 v6 帶來的影響

          • 攔截,安排上了。
          • withRouter,安排上了。

          路由好了,那么路由懶加載得有吧,怎么搞?

          方式還是依然是通過 React.lazy配合import的動態(tài)引入,代碼如下。

          const Login = React.lazy(() => import('./login'))
          復制代碼

          然后還要在通過React.Suspense包裹一下這個懶加載組件,否則的話會報錯,這個問題我的那個朋友可是卡住了很久。。。,原因就是忘記了要在懶加載組件外包裹一層React.Suspense

          ...}>{}
          復制代碼

          但是,朋友又跟我講,每加一個頁面,就寫個lazy引入組件和Suspense包裹,那么頁面一多,代碼就會變成這樣:

          const Login = React.lazy(() => import('./pages/login'))
          const PageCenter = React.lazy(() => import('./pages/pageCenter'))
          const Page1 = React.lazy(() => import('./pages/page1'))
          const Page2 = React.lazy(() => import('./pages/page2'))
          const Page3 = React.lazy(() => import('./pages/page3'))
          const Page4 = React.lazy(() => import('./pages/page4'))
          const Page5 = React.lazy(() => import('./pages/page5'))
          ...
          export default () => {
          return useRoutes([
          {
          path: '/',
          element: ...}>{}
          children: [
          { path: "codePLay", element: },
          ]
          },
          {
          path: '/pageCenter',
          children: [
          {
          path: '/page1',
          element: ...}>{}
          },
          {
          path: '/page2',
          element: ...}>{}
          },
          {
          path: '/page3',
          element: ...}>{}
          },
          {
          path: '/page4',
          element: ...}>{}
          },
          {
          path: '/page5',
          element: ...}>{}
          },
          ]
          },
          {
          path: '/404',
          element:
          not found

          },
          ])
          }
          復制代碼

          嵌套路由

              //PageCenter.tsx
          import React from 'react'
          export default () => {
          return (



          )
          }
          )
          復制代碼

          這樣看起來就非常的冗余,很多重復的代碼,希望我能幫他優(yōu)化一下,em ~~~沒問題,開整。

          優(yōu)化代碼

          主要從兩個方面入手:

          • 組件lazy引入上
          • 然后Suspense包裹上

          統(tǒng)一入口

          首先頁面組件都放在了pages路徑下,然后再定向導入,我們加個indexpages文件夾下,進行統(tǒng)一管理。

          //?文件:pages/index.ts
          export?Login?=?React.lazy(()?=>?import('./pages/login'))
          export?Page1?=?React.lazy(()?=>?import('./pages/page1'))
          export?Page2?=?React.lazy(()?=>?import('./pages/page2'))
          export?Page3?=?React.lazy(()?=>?import('./pages/page3'))
          export?Page4?=?React.lazy(()?=>?import('./pages/page4'))
          export?Page5?=?React.lazy(()?=>?import('./pages/page5'))
          復制代碼

          然后我們重構一下之前的引入代碼:

          const { Login, Page1, Page2, Page3, Page4, Page5 } from './pages'
          復制代碼

          封裝包裝組件,支持多類型

          寫一個能夠包裝多類型的組件,都可以包裝:

          • 組件,包括:函數(shù)組件類組件
          • lazy 組件
          • jsx element

          那么代碼如下:

          //?加載異步組件的loading
          type?ChildT?=?React.LazyExoticComponent<()?=>?JSX.Element>?|?React.FC
          export?const?wrapper?=?(Child:?ChildT,?cutonFallBack?:?CutonFallBackT)?=>?{
          ??//?判斷jsx
          ??if?(Child.type?&&?!Child._init?&&?!Child._payload)?{
          ????return?Child
          ??}?else?{
          ????//?判斷是否為clas和function組件
          ????if?(typeof?Child?===?'function')?{
          ??????return?<Child>Child>
          ????}?else?{
          ??????//?判斷是否為lazy組件
          ??????return?(
          ????????<React.Suspense?fallback={cutonFallBack?||?<>...}>
          ??????????{</Child>}
          ????????React.Suspense>
          ??????)
          ????}
          ??}
          }
          復制代碼

          那么這樣整體重構后的代碼,就大體變成了

          const { Login,PageCenter, Page1, Page2, Page3, Page4, Page5 } from './pages'
          ...
          export default () => {
          return useRoutes([
          {
          path: '/',
          element:wrapper(Login),
          },
          {
          path: '/pageCenter',
          children: [
          {
          path: '/page1',
          element: wrapper(Page1)
          },
          {
          path: '/page2',
          element: wrapper(Page2)
          },
          {
          path: '/page3',
          element: wrapper(Page3)
          },
          {
          path: '/page4',
          element: wrapper(Page4)
          },
          {
          path: '/page5',
          element: wrapper(Page5)
          },
          ]
          },
          {
          path: '/404',
          element: wrapper(
          not found
          )
          },
          ])
          }
          復制代碼

          em ~~~樸實無華,但是代碼看起來舒服不少,朋友感嘆學到不少干貨,我感覺這就是基本操作,233333。


          關于本文

          作者:閑D阿強

          https://juejin.cn/post/7085674288933502984


          往期推薦


          阿里前端:我的老婆失業(yè)了,周圍同事也在不斷被裁
          2022,VSCode 前端插件推薦
          前端JS 燒腦面試題大賞

          最后


          • 歡迎加我微信,拉你進技術群,長期交流學習...

          • 歡迎關注「前端Q」,認真學前端,做個專業(yè)的技術人...

          點個在看支持我吧
          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青青草视频在线免费观看 | 国产激情视频在线观看 | 国产精品人妻无码久久 | 中国女人如毛片 | 免费看无码一级A片在线播放 |