最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React?路由使用示例詳解

 更新時(shí)間:2022年05月27日 10:15:29   作者:QiShare  
這篇文章主要介紹了React?路由使用,使用路由時(shí)需要為組件指定一個(gè)路由的path,最終會(huì)以path為基礎(chǔ),進(jìn)行頁面的跳轉(zhuǎn),具體使用先看個(gè)簡(jiǎn)單示例,該示例比較簡(jiǎn)單就是兩個(gè)Tab頁面的來回切換

Router

react-router-dom是一個(gè)處理頁面跳轉(zhuǎn)的三方庫,在使用之前需要先安裝到我們的項(xiàng)目中:

# npm
npm install react-router-dom@6
#yarn
yarn add react-router-dom@6

簡(jiǎn)單路由

使用路由時(shí)需要為組件指定一個(gè)路由的path,最終會(huì)以path為基礎(chǔ),進(jìn)行頁面的跳轉(zhuǎn)。具體使用先看個(gè)簡(jiǎn)單示例,該示例比較簡(jiǎn)單就是兩個(gè)Tab頁面的來回切換。

///導(dǎo)入路由
import {Link} from 'react-router-dom'
function App() {
  return (
    <div>
      <h1>路由練習(xí)</h1>
      <nav>
        {/* link 頁面展示時(shí),是個(gè)a標(biāo)簽 */}
        <Link className ='link' to='/Tab1'> Tab1</Link> ///覆蓋:渲染tab1組件
        <Link className = 'link' to='/Tab2'> Tab2 </Link> ///覆蓋:渲染tab2組件
      </nav>
    </div>
    );
}
///路由頁面1
export default function Tab1(params) {
    return (
        // 文檔中,<main> 元素是唯一的,所以不能出現(xiàn)一個(gè)以上的 <main> 元素
        <main style={{ padding: "1rem 0" }}>
          <h2>我是Tab1</h2>
        </main>
      );
}
///路由頁面2
export default function Tab2(params) {
    return (
        <main style={{ padding: "1rem 0" }}>
          <h2>我是Tab2</h2>
        </main>
      );
}
///在index.js中配置路由
import {BrowserRouter,Routes,Route} from 'react-router-dom'
import Tab1 from './pages/Tab1.jsx'
import Tab2 from './pages/Tab2.jsx'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
     <Routes>
       <Route path = '/' element = {<App/>} /> ///兄弟路由
       <Route path = '/Tab1' element = {<Tab1/>} />///兄弟路由
       <Route path = '/Tab2' element = {<Tab2/>} />///兄弟路由
     </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

最終交互時(shí),上述路由配置會(huì)出現(xiàn)彼此覆蓋的情況,如下圖:

為了保證App組件,不會(huì)在Tab1Tab2切換時(shí)被覆蓋需要使用嵌套路由。

嵌套路由

嵌套路由,可以保證子路由共享父路由的界面而不會(huì)覆蓋。為此React提供了Outlet組件,將其用于父組件中可以為子路由的元素占位,并最終渲染子路由的元素。

Outlet渲染一個(gè)子路由的元素

import {Link,Outlet} from 'react-router-dom'
function App() {
  return (
    <div>
      <h1>路由練習(xí)</h1>
      <nav>
        {/* link 頁面展示時(shí),是個(gè)a標(biāo)簽 */}
        <Link className ='link' to='/Tab1'> Tab1</Link> 
        <Link className ='link' to='/Tab2'> Tab2 </Link>
      </nav>
      {/* 此時(shí)尚不能實(shí)現(xiàn)共享APP UI的同時(shí)渲染出 Tab1 和 Tab2,還需要使用 <Outlet/>
        保證父路由,在子路由交換時(shí),仍然存在
      */}
      <Outlet/>
    </div>
    );
}

///index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
       <Route path='/' element={<App />} >
          {/* 孩子路由,url為:  / + 孩子的path */}
          <Route path='Tab1' element={<Tab1 />} /> 
          <Route path='Tab2' element={<Tab2 />} />
        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

最終效果如下圖:

未匹配路由

通過path='*',實(shí)現(xiàn)沒有其他路由匹配時(shí),對(duì)其進(jìn)行匹配。

root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
      <Route path='/' element={<App />} >
          {/* 孩子路由,url為:  / + 孩子的path */}
          <Route path='Tab1' element={<Tab1 />} /> 
          <Route path='Tab2' element={<Tab2 />} />
          <Route path = '*' element={<p>
            未匹配到路由時(shí),會(huì)跳轉(zhuǎn)此處。
          </p>} />
        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

效果如圖:

路由傳參數(shù)

通過路由傳遞參數(shù)到組件中

///模擬數(shù)據(jù)
const dataList = [
    {
        id:20220101,
        content:'筆記1'
    },
    {
        id:20220102,
        content:'筆記2'
    },
    {
        id:20220103,
        content:'筆記3'
    },
]
export default function getTodoList(params) {
    return dataList
}

export function findTodoItem(params) {
    return dataList.find((value)=>value.id === params)
}
///組件Tab2中定義列表
export default function Tab2(params) {
    let list = getTodoList()
    return (
        <div>
            <ul>
                {
                    list.map((item) => (
                        <li key={item.id}>
                           {/*子路由形如:'/Tab2/20220103' */}
                            <Link to={`/Tab2/${item.id}`}>{item.content}</Link>
                        </li>
                    ))
                }
            </ul>
           {/*渲染一個(gè)子路由的元素*/}
            <Outlet />
        </div>
    );
}

///注冊(cè)列表項(xiàng)的子路由
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
      <Route path='/' element={<App />} >
          {/* 孩子路由,url為:  / + 孩子的path */}
          <Route path='Tab1' element={<Tab1 />} /> 
          <Route path='Tab2' element={<Tab2 />} >
            <Route path=':itemId' element={<ItemDetail/>}/>
          </Route>
          <Route path = '*' element={<p>未匹配到該路由請(qǐng)先設(shè)置路由頁面 </p>} />
        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

///定義Tab2子組件 ItemDetail
import { useParams } from 'react-router-dom'
export function ItemDetail() {
    //點(diǎn)擊每一項(xiàng)的鏈接,注意:URL 發(fā)生了變化,但新的組件尚未顯示
    ///需要父組件中添加<Outlet>
    ///HOOK 獲取路由中的參數(shù),形如{itemId:'20220102'}
    let params = useParams()
    let content = findTodoItem(parseInt(params.itemId)).content
    return (
        <div>
            <h2>筆記詳情</h2>
            <p>這是我于{params.itemId},記錄的筆記他的內(nèi)容為{content}</p>
        </div>
    )
}

最終效果:

索引路由

當(dāng)我們切換至Tab1再切回Tab2后,筆記詳情頁面將空白,效果如下:

可以通過索引路由填補(bǔ)空白,具體只需:

root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
      <Route path='/' element={<App />} >
          {/* 孩子路由,url為:  / + 孩子的path */}
          <Route path='Tab1' element={<Tab1 />} /> 

          <Route path='Tab2' element={<Tab2 />} >
            {/*索引路由 有index 無path*/}
            <Route index element={<p>請(qǐng)選擇一個(gè)筆記查看它的詳情 </p>}/>
            <Route path=':itemId' element={<ItemDetail/>}/>
          </Route>
          
          <Route path = '*' element={<p>未匹配到該路由請(qǐng)先設(shè)置路由頁面 </p>} />

        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

如此當(dāng)我們重復(fù)上述操作時(shí)便會(huì)呈現(xiàn)如下效果:

當(dāng)父路由匹配,但其他子路由都不匹配時(shí),由索引路由匹配。索引路由是父路由的默認(rèn)子路由。 當(dāng)用戶尚未單擊導(dǎo)航列表中的一項(xiàng)時(shí),會(huì)呈現(xiàn)索引路由。

活動(dòng)鏈接

Link功能一致,差異是可以設(shè)置點(diǎn)擊后的顏色

export default function Tab2(params) {
    let list = getTodoList()
    return (
        <div>
            <ul>
                {
                    list.map((item) => (
                        <li key={item.id}>
                            {/* <Link to={`/Tab2/${item.id}`}>{item.content}</Link> */}
                            <NavLink style = { ({isActive})=> ({ color : isActive ? "red" : "" }) } to={`/Tab2/${item.id}`}> {item.content} </NavLink>
                        </li>
                    ))
                }
            </ul>
            <Outlet />
        </div>
    );
}

搜索參數(shù)

搜索參數(shù)類似于 URL 參數(shù),形如/login?success=1

export default function Tab2(params) {
    let list = getTodoList()
    ///和React.useState很像
    let [searchParams, setSearchParams] = useSearchParams();
    return (
        <div>
            {/* 搜索框: 隨著輸入設(shè)置搜索參數(shù) */}
            <input type="text" onChange = { (event)=>{
                let text = event.target.value
                if (text) {
                    setSearchParams({text})
                } else {
                    setSearchParams({})
                }
            } } />

            <ul>
                { list.filter((item)=>{
                    let txt = searchParams.get('text')
                    if (!txt) return true
                    return item.content.startsWith(txt)
                })
                    .map((item) => (
                        <li key={item.id}>
                            {/* <Link to={`/Tab2/${item.id}`}>{item.content}</Link> */}
                            <NavLink style = { ({isActive})=> ({ color : isActive ? "red" : "" }) } to={`/Tab2/${item.id}`}> {item.content} </NavLink>
                        </li>
                    ))
                }
            </ul>

            <Outlet />
        </div>
    );
}

隨著我們輸入apple, 路由的地址將變?yōu)?code>/Tab2?text=apple觸發(fā)路由重新呈現(xiàn)。

當(dāng)我們?cè)谳斎肟蜉斎胱址麜r(shí),便會(huì)觸發(fā)列表的過濾顯示:

自定義行為

上述UI在交互過程中,當(dāng)我們點(diǎn)擊Tab1Tab2進(jìn)行切換時(shí),或者點(diǎn)擊appleappet時(shí),會(huì)出現(xiàn)輸入框被清空,且列表不再被過濾的問題。

react-router提供了useLocation方法,它返回瀏覽器顯示的url信息。通過它可以獲取瀏覽器url中的搜索參數(shù),從而進(jìn)行暫存,在具體組件內(nèi),可以通過useSearchParams獲取到暫存的值。具體方式,通過自定義組件包裝NavLinkLink來實(shí)現(xiàn)。

///1.自定義`QueryLink`組件
import React, { Component } from 'react';
import { useLocation,NavLink } from "react-router-dom";
export default function QueryLink({to,...props}) {
  ///代表當(dāng)前瀏覽器顯示的url
  // location內(nèi)容:{pathname: '/Tab2', search: '?text=ad', hash: '', state: null, key: 'dhvg8xme'}
  let location = useLocation()
  // to = '/Tab2?text=ad'
  return <NavLink to={to+location.search} {...props} />
}
//2. 替換 `tab1`、`tab2`的link or Navlink
<QueryLink className ='link' to='/Tab1'> Tab1</QueryLink> 
<QueryLink className ='link' to='/Tab2'> Tab2 </QueryLink>
//3. 替換列表項(xiàng)的link or Navlink
 <li key={item.id}>
   <QueryLink style = { ({isActive})=> ({ color : isActive ? "red" : "" }) } to={`/Tab2/${item.id}`}> {item.content} </QueryLink>
 </li>

useNavigate

上述示例中,路由的切換采用Link或者NavLink,但當(dāng)我們的頁面元素不使用Link時(shí),比如使用Button,此時(shí)便需要使用采用useNavigate。同上可以配合useLocation保存搜索字段。

export function ItemDetail() {
    //點(diǎn)擊每一項(xiàng)的鏈接,注意:URL 發(fā)生了變化,但新的組件尚未顯示
    ///需要父組件中添加<Outlet>
    let params = useParams()
    let content = findTodoItem(parseInt(params.itemId)).content
    ///返回函數(shù)
    let navigate = useNavigate()
    ///獲取搜索字段
    let location = useLocation()
    return (
        <div>
            <h2>筆記詳情</h2>
            <p>這是我于{params.itemId}記錄的筆記,內(nèi)容為{content}</p>
            <button onClick = {
                (e)=>{
                    deleteTodoItem(params.itemId)
                    navigate('/Tab2/'+location.search)
                }
            }>
                刪除筆記
            </button>
        </div>
    )
}
// src/data.jsx
export function deleteTodoItem(params) {
    dataList = dataList.filter((value)=>value.id !== parseInt(params)) 
}

參考資料

reactrouter.com/docs/en/v6/…

到此這篇關(guān)于React 路由使用的文章就介紹到這了,更多相關(guān)React 路由使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

到此這篇關(guān)于React 路由使用示例詳解的文章就介紹到這了,更多相關(guān)React 路由使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React實(shí)現(xiàn)預(yù)覽展示docx和Excel文件

    React實(shí)現(xiàn)預(yù)覽展示docx和Excel文件

    這篇文章主要為大家詳細(xì)介紹了如何使用React實(shí)現(xiàn)預(yù)覽展示docx和Excel文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • React如何解決樣式污染問題

    React如何解決樣式污染問題

    這篇文章主要介紹了React如何解決樣式污染問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • react使用websocket實(shí)時(shí)通信方式

    react使用websocket實(shí)時(shí)通信方式

    這篇文章主要介紹了react使用websocket實(shí)時(shí)通信方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • react-native 封裝選擇彈出框示例(試用ios&android)

    react-native 封裝選擇彈出框示例(試用ios&android)

    本篇文章主要介紹了react-native 封裝選擇彈出框示例(試用ios&android),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • 詳解react-router 4.0 下服務(wù)器如何配合BrowserRouter

    詳解react-router 4.0 下服務(wù)器如何配合BrowserRouter

    這篇文章主要介紹了詳解react-router 4.0 下服務(wù)器如何配合BrowserRouter,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • 在React中使用React.createRef:更優(yōu)雅的DOM引用方式

    在React中使用React.createRef:更優(yōu)雅的DOM引用方式

    React提供了多種方式來引用DOM元素,其中React.createRef()是一種更為現(xiàn)代、更優(yōu)雅的方式,在這篇文章中,我們將深入了解React.createRef()的應(yīng)用,以及它為開發(fā)者帶來的便利,感興趣的朋友一起看看吧
    2024-01-01
  • 解決React報(bào)錯(cuò)Property does not exist on type 'JSX.IntrinsicElements'

    解決React報(bào)錯(cuò)Property does not exist on 

    這篇文章主要為大家介紹了React報(bào)錯(cuò)Property does not exist on type 'JSX.IntrinsicElements'解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React Native:react-native-code-push報(bào)錯(cuò)的解決

    React Native:react-native-code-push報(bào)錯(cuò)的解決

    這篇文章主要介紹了React Native:react-native-code-push報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • react中的axios模塊你了解嗎

    react中的axios模塊你了解嗎

    這篇文章主要為大家詳細(xì)介紹了react中的axios模塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Reactjs實(shí)現(xiàn)通用分頁組件的實(shí)例代碼

    Reactjs實(shí)現(xiàn)通用分頁組件的實(shí)例代碼

    這篇文章主要介紹了Reactjs實(shí)現(xiàn)通用分頁組件的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-01-01

最新評(píng)論

黄陵县| 江北区| 九龙城区| 临汾市| 兰坪| 综艺| 岑溪市| 山西省| 吴川市| 灵山县| 黔东| 云浮市| 龙州县| 陵水| 如东县| 邹城市| 宜春市| 小金县| 井陉县| 新营市| 静乐县| 望都县| 曲沃县| 乐清市| 盐城市| 屯留县| 蒙阴县| 巴马| 茂名市| 寻乌县| 蒙城县| 微博| 修文县| 定兴县| 大同市| 三台县| 织金县| 两当县| 罗江县| 潼关县| 芦山县|