<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>

          無廢話 | 快速上手React路由

          共 22389字,需瀏覽 45分鐘

           ·

          2021-04-26 18:27


          點擊上方“前端Sharing”,選擇“設(shè)為星標
          第一時間關(guān)注技術(shù)干貨!


          本文以簡潔為目標,幫助快速上手react-router-dom默認你接觸過路由相關(guān)的開發(fā)

          安裝

          輸入以下命令進行安裝:

          // npm
          npm install react-router-dom

          // yarn
          yarn add react-router-dom

          react-router相關(guān)標簽

          react-router常用的組件有以下八個:

          import { 
            BrowserRouter,
            HashRouter,
            Route,
            Redirect,
            Switch,
            Link,
            NavLink,
            withRouter,
          from 'react-router-dom'

          簡單路由跳轉(zhuǎn)

          實現(xiàn)一個簡單的一級路由跳轉(zhuǎn)

          import { 
              BrowserRouter as Router, 
              Route, 
              Link 
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  <Link to="/home" className="link">跳轉(zhuǎn)Home頁面</Link>
                  <Link to="/about" className="link">跳轉(zhuǎn)About頁面</Link>
                  <Route path="/home" component={Home}/>
                  <Route path="/about" component={About}/>
                </Router>
              </div>

            );
          }

          export default App;

          效果如下:

          要點總結(jié):

          1. Route組件必須在Router組件內(nèi)部
          2. Link組件的to屬性的值為點擊后跳轉(zhuǎn)的路徑
          3. Route組建的path屬性是與Link標簽的to屬性匹配的; component屬性表示Route組件匹配成功后渲染的組件對象

          嵌套路由跳轉(zhuǎn)

          React 的路由匹配層級是有順序的

          例如,在 App 組件中,設(shè)置了兩個路由組件的匹配路徑,分別是 /home/about,代碼如下:

          import { 
            BrowserRouter as Router, 
            Route, 
            Link,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({

            return (
              <div className="App">
                <Router>
                  <Link to="/home">跳轉(zhuǎn)Home頁面</Link>
                  <Link to="/about">跳轉(zhuǎn)About頁面</Link>

                  <Route path="/home" component={Home}/>
                  <Route path="/about" component={About}/>                           

                </Router>
              </div>

            );
          }

          export default App;

          然后 Home 組件中同樣也想設(shè)置兩個路由組件的匹配路徑,分別是 /home/one/home/two,此時就可以看出,這個 /home/one/home/two 為上一級路由 /home 的二級嵌套路由,代碼如下:

          import React from 'react'
          import {
              Route,
              Link,
          from 'react-router-dom'
          import One from './one'
          import Two from './two'

          function Home ({
              
              return (
                  <>
                      我是Home頁面
                      <Link to="/home/one">跳轉(zhuǎn)到Home/one頁面</Link>
                      <Link to="/home/two">跳轉(zhuǎn)到Home/two頁面</Link>

                      <Route path="/home/one" component={One}/>
                      <Route path="/home/two" component={Two}/>
                  </>

              )
          }

          export default Home

          特別注意: Home 組件中的路由組件 One 的二級路由路徑匹配必須要寫 /home/one ,而不是 /one ,不要以為 One 組件看似在 Home 組件內(nèi)就可以簡寫成 /one

          動態(tài)鏈接

          NavLink可以將當(dāng)前處于active狀態(tài)的鏈接附加一個active類名,例如:

          import { 
              BrowserRouter as Router, 
              Route, 
              NavLink 
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  <NavLink to="/home" className="link">跳轉(zhuǎn)Home頁面</NavLink>
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>
                  <Route path="/home" component={Home}/>
                  <Route path="/about" component={About}/>
                </Router>
              </div>

            );
          }

          export default App;
          /* 設(shè)置active類的樣式 */
          .active {
              font-weight: blod;
              color: red;
          }

          效果如下:

          路由匹配優(yōu)化

          當(dāng)點擊跳轉(zhuǎn)鏈接時,會自動去嘗試匹配所有的Route對應(yīng)的路徑,如圖所示:

          正常情況下,只需匹配到一個規(guī)則,渲染即可,即匹配成功一個后,無需進行后續(xù)的匹配嘗試,此時可以用Switch組件,如下所示:

          import { 
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  <NavLink to="/home" className="link">跳轉(zhuǎn)Home頁面</NavLink>   
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>

                  <Switch>
                    <Route path="/home" component={Home}/>       
                    <Route path="/about" component={About}/>      
                    <Route path="/home" component={Home}/>       
                    <Route path="/home" component={Home}/>        
                    {/* 此處省略一萬個Route組件 */}                  
                    <Route path="/home" component={Home}/>                           
                  </Switch>

                </Router>
              </div>

            );
          }

          export default App;

          效果如下:

          要點總結(jié):

          1. 將多個Route組件同時放在一個Switch組件中,即可避免多次無意義的路由匹配,以此提升性能

          重定向

          當(dāng)頁面跳轉(zhuǎn)時,若跳轉(zhuǎn)鏈接沒有匹配上任何一個 Route 組件,那么就會顯示 404 頁面,所以我們需要一個重定向組件 Redirect ,代碼如下:

          import { 
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
            Redirect,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  <NavLink to="/home" className="link">跳轉(zhuǎn)Home頁面</NavLink>   
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>
                  <NavLink to="/shop" className="link">跳轉(zhuǎn)Shop頁面</NavLink>   {/* 點擊,跳轉(zhuǎn)到/shop,但該路徑?jīng)]有設(shè)置 */}

                  <Switch>
                    <Route path="/home" component={Home}/>       
                    <Route path="/about" component={About}/>      
                    <Redirect to="/home" />    {/* 當(dāng)以上Route組件都匹配失敗時,重定向到/home */}                    
                  </Switch>

                </Router>
              </div>

            );
          }

          export default App;

          效果如下:

          路由傳參

          所有路由傳遞的參數(shù),都會在跳轉(zhuǎn)路由組件的 props 中獲取到,每種傳參方式接收的方式略有不同

          路由傳參的方式一共有三種,依次來看一下

          第一種

          第一種是在 Link 組件的跳轉(zhuǎn)路徑上攜帶參數(shù),并在 Route 組件的匹配路徑上通過 :參數(shù)名 的方式接收參數(shù),代碼如下:

          import { 
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  {/* 在 /home 的路徑上攜帶了 張三、18 共兩個參數(shù) */}
                  <NavLink to="/home/張三/18" className="link">跳轉(zhuǎn)Home頁面</NavLink>   
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>

                  <Switch>
                    {/* 在 /home 匹配路徑上相同的位置接收了 name、age 兩個參數(shù) */}
                    <Route path="/home/:name/:age" component={Home}/>       
                    <Route path="/about" component={About}/>                           
                  </Switch>

                </Router>
              </div>

            );
          }

          export default App;

          嘗試跳轉(zhuǎn),并打印一下路由組件的 props

          可以看到,第一種方式的參數(shù)是通過 props.match.params 來獲取的

          第二種

          第二種方式就是通過在 Link 組件的跳轉(zhuǎn)鏈接后面跟上以 ? 開頭,類似 ?a=1&b=3 這樣的參數(shù)進行傳遞,代碼如下:

          import { 
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  {/* 在跳轉(zhuǎn)路徑后面以?開頭傳遞兩個參數(shù),分別為name=張三、age=18 */}
                  <NavLink to="/home?name=張三&age=18" className="link">跳轉(zhuǎn)Home頁面</NavLink>   
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>

                  <Switch>
                    {/* 此處無需做接收操作 */}
                    <Route path="/home" component={Home}/>       
                    <Route path="/about" component={About}/>                           
                  </Switch>

                </Router>
              </div>

            );
          }

          export default App;

          嘗試跳轉(zhuǎn),并打印一下路由組件的 props

          可以看到,第二種方式的參數(shù)是通過 props.location.search 來獲取的,不過這里的參數(shù)需要自己簡單做進一步轉(zhuǎn)化,這里就不做過多說明了

          第三種

          第三種方式就是以對象的形式編寫 Link 組件的 to 跳轉(zhuǎn)屬性,并通過 state 屬性來傳遞參數(shù),代碼如下:

          import { 
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  {/* 以對象的形式描述to屬性,路徑屬性名為pathname,參數(shù)屬性名為state */}
                  <NavLink to={{pathname: "/home", state: {name: '張三', age: 18}}} className="link">跳轉(zhuǎn)Home頁面</NavLink>   
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>

                  <Switch>
                    {/* 此處無需特地接收屬性 */}
                    <Route path="/home" component={Home}/>       
                    <Route path="/about" component={About}/>                           
                  </Switch>

                </Router>
              </div>

            );
          }

          export default App;

          嘗試跳轉(zhuǎn),并打印一下路由組件的 props

          可以看到,第三種方式的參數(shù)是通過 props.location.state 來獲取的

          函數(shù)式路由

          以上主要都是通過 react-router-dom 中的 Link 組件來往某個路由組件跳轉(zhuǎn)

          但有時,我們需要更靈活的方式進行跳轉(zhuǎn)路由,例如通過調(diào)用一個函數(shù),隨時隨地進行路由跳轉(zhuǎn),這就叫函數(shù)式路由

          函數(shù)式路由用到的方法有以下 5 個(下方截圖來自路由組件props

          5 個方法分別是 pushreplace、goForwardgoBack、go,接下來按順序介紹一下這幾個方法

          push

          push 方法就是使頁面跳轉(zhuǎn)到對應(yīng)路徑,并在瀏覽器中留下記錄(即可以通過瀏覽器的回退按鈕,返回上一個頁面)

          舉個例子:在路由組件 Home 中設(shè)置一個按鈕 button ,點擊后調(diào)用 push 方法,跳轉(zhuǎn)到 /about 頁面

          import React from 'react'

          function Home (props{

              let pushLink = () => {
                  props.history.push('/about')
              }
              
              return (
                  <div className="a">
                      我是Home頁面
                      <button onClick={pushLink}>跳轉(zhuǎn)到about頁面</button>
                  </div>

              )
          }

          export default Home

          跳轉(zhuǎn)效果如下:

          可以看到,通過 push 方法跳轉(zhuǎn)以后,可以通過瀏覽器的回退按鈕,返回上一個頁面

          replace

          replace 方法與 push 方法類似,不一樣的地方就是,跳轉(zhuǎn)后不會在瀏覽器中保存上一個頁面的記錄(即無法通過瀏覽器的回退按鈕,返回上一個頁面)

          改動一下代碼

          import React from 'react'

          function Home (props{

              let replaceLink = () => {
                  props.history.replace('/about')
              }
              
              return (
                  <div className="a">
                      我是Home頁面
                      <button onClick={replaceLink}>跳轉(zhuǎn)到about頁面</button>
                  </div>

              )
          }

          export default Home

          跳轉(zhuǎn)效果如下:

          可以看到,剛開始的路徑是 '/' ,然后跳轉(zhuǎn)到 '/home' ,再點擊按鈕,通過 replace 方法跳轉(zhuǎn)到 /about 頁面。最后通過瀏覽器的回退按鈕返回到了 / 頁面,說明中間的 /home 沒有被存在瀏覽器的記錄里

          goForward

          調(diào)用 goForward 方法,就相當(dāng)于點擊了瀏覽器的返回下一個頁面按鈕,如下圖所示:

          這里就不做過多演示了

          goBack

          調(diào)用 goBack 方法,就相當(dāng)于點擊了瀏覽器的返回上一個頁面的按鈕,如下圖所示:

          go

          go 方法顧名思義,是用于跳轉(zhuǎn)到指定路徑的。

          該方法接受一個參數(shù)(參數(shù)類型為 Number),情況如下:

          1. 當(dāng)參數(shù)為正數(shù) n 時,表示跳轉(zhuǎn)到下 n 個頁面。例如 go(1) 相當(dāng)于調(diào)用了一次 goForward 方法
          2. 當(dāng)參數(shù)為負數(shù) n 時,表示跳轉(zhuǎn)到上 n 個頁面。例如 go(-3) 相當(dāng)于調(diào)用了三次 goBack 方法
          3. 當(dāng)參數(shù)為 0 時,表示刷新當(dāng)前頁面

          普通組件使用路由

          這里區(qū)分兩個概念,分別為 普通組件路由組件

          通過 Route 組件渲染的組件為路由組件 ,其余的基本上都為 普通組件

          例如,下方代碼中:Home 組件為路由組件 ; App 組件為普通組件

          import {
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
          from 'react-router-dom'
          import Home from './home'

          export default function App({
            
            return (
              <div className="App">
                <Router>
                  <NavLink to='/home' className="link">跳轉(zhuǎn)Home頁面</NavLink>   

                  <Switch>
                    <Route path="/home" component={Home}/>                              
                  </Switch>

                </Router>
              </div>

            );
          }

          然后,路由組件跟普通組件最大的區(qū)別就是,組件的 props 屬性中是否有下圖所示的內(nèi)容:(前者有,后者無)

          此時,react-router-dom 提供了一個 withRouter 方法,可以使普通組件也能像路由組件一樣有那些方法或數(shù)據(jù)可以使用

          使用方法如下:

          import { 
            BrowserRouter as Router, 
            Route, 
            NavLink,
            Switch,
            withRouter,  // 1. 引入 witRouter
          from 'react-router-dom'
          import About from './about'

          function App(props{

            console.log(props);   // 3. 嘗試打印普通組件App的props,發(fā)現(xiàn)此時props中已有內(nèi)容了,即普通組件也能擁有跟路由組件一樣類似的功能

            return (
              <div className="App">
                <Router>
                  <NavLink to="/about" className="link">跳轉(zhuǎn)About頁面</NavLink>

                  <Switch>
                    <Route path="/about" component={About}/>                           
                  </Switch>

                </Router>
              </div>

            );
          }

          export default withRouter(App);  // 2. 通過withRouter方法對普通組件做一層包裝處理

          補充

          replace

          在函數(shù)式路由里跳轉(zhuǎn)類型主要有兩種,分別是 pushreplace,那么在非函數(shù)式路由中,同樣也可以自定義跳轉(zhuǎn)類型,具體的實現(xiàn)代碼如下:

          import { 
              BrowserRouter as Router, 
              Route, 
              Link 
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({
            return (
              <div className="App">
                <Router>
                  <Link to="/home" className="link">跳轉(zhuǎn)Home頁面</Link>
                  <Link to="/about" className="link">跳轉(zhuǎn)About頁面</Link>

                  <Route path="/home" component={Home} replace={true}/>  {/* replace為true,跳轉(zhuǎn)類型為replace */}
                  <Route path="/about" component={About} replace={false}/>   {/* replace為false,跳轉(zhuǎn)類型為push */}
                </Router>
              </div>

            );
          }

          export default App;

          Route 組件上有個 replace 屬性可以設(shè)定跳轉(zhuǎn)類型,當(dāng)值為 true 時,跳轉(zhuǎn)類型為 replace ; 為 false 時,跳轉(zhuǎn)類型為 push

          excat

          路由的匹配默認是模糊匹配的,舉個例子:

          import { 
            BrowserRouter as Router, 
            Route, 
            Link,
          from 'react-router-dom'
          import Home from './home'
          import About from './about'

          function App({

            return (
              <div className="App">
                <Router>
                  <Link to="/home/abc">跳轉(zhuǎn)Home頁面</Link>    {/* 跳轉(zhuǎn)到/home/abc,但實際home下沒有abc這個路由組件 */}
                  <Link to="/about/abc">跳轉(zhuǎn)About頁面</Link>  {/* 跳轉(zhuǎn)到/about/abc,但實際home下也沒有abc這個路由組件 */}

                  <Route path="/home" component={Home} />    {/* 路由匹配規(guī)則為/home,沒有設(shè)置exact屬性,當(dāng)前為模糊匹配 */}
                  <Route path="/about" component={About} exact/>   {/* 路由匹配規(guī)則為/about,設(shè)置了exact屬性,當(dāng)前為精準匹配 */}

                </Router>
              </div>

            );
          }

          export default App;

          效果如下:

          圖中看出,因為跳轉(zhuǎn) /home/abc 時,第一個 Route 組件是模糊匹配的,所以先匹配到了 /home,因此 Home 組件渲染了 ; 而跳轉(zhuǎn) /about/abc 時,第二個 Route 組件是精準匹配的,即 /about/abc 不等于 /about,所以 About 組件也沒有渲染

          總結(jié):

          1. 如果想要精準匹配的話,只需要將 Route 組件的 exact 屬性設(shè)置為 true 即可
          2. 精準匹配要謹慎使用,因為可能會影響嵌套路由的使用


          本文為公眾號【前端Sharing】

          關(guān)注我,閱讀更多精彩內(nèi)容

          ▽▽▽



          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  最新国产免费地址 | 亚州无码人妻 | wWW香焦yeyeLu | 狼人入口国产 | 午夜三区 |