一、React路由簡介
React 官方并沒有提供對應(yīng)的路由插件,因此,我們需要下載第三方的路由插件 —— React Router DOM。
React Router 在 2021 年 11 月份的時候更新 v6 的版本。本次課就主要講解V6版本
二、路由配置
1、下載路由
在項目根目錄中,通過以下命令
yarn add react-router-dom
2、路由配置
1)首先在react項目的入口文件index.js文件中,使用<BrowserRouter>
將<App>
包裹起來
import {BrowserRouter} from 'react-router-dom'
?
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
? ?<BrowserRouter>
? ? ? ?<App />
? ?</BrowserRouter>
);
BrowserRouter
:包裹這個應(yīng)用,一個React應(yīng)用只需使用一次
在 React Router 中提供了兩種路由模式:hash 和 history。
對應(yīng)的的路由組件分別是:
-
HashRouter:hash 模式的路由
-
BrowserRouter:history 模式的路由
實際使用時,任選其中一個模式引入即可
2)其次,在App.js文件中,使用<Routes>
設(shè)置路由出口,使用<Route>
指定導(dǎo)航鏈接
import React from 'react'
import {Routes,Route} from 'react-router-dom'
import Login from './pages/Login'
import Register from './pages/Register'
import Home from './pages/Home'
export default function App() {
?return (
? <Routes>
? ? <Route path='/login' element={<Login/>}></Route>
? ? <Route path='/register' element={<Register/>}></Route>
? ? <Route path='/' element={<Home/>}></Route>
? </Routes>
)
}
核心組件作用說明
-
Routes
:提供一個路由出口,滿足條件的路由組件會渲染到組件內(nèi)部 -
Route
: 用于指定導(dǎo)航鏈接,完成路由跳轉(zhuǎn)-
path
:path屬性指定匹配的路徑地址 -
element
element屬性指定要渲染的組件
-
三、路由跳轉(zhuǎn)
React Router 中,路由的跳轉(zhuǎn)分為兩種方式:
-
標(biāo)簽(組件)跳轉(zhuǎn)
-
JS(API)跳轉(zhuǎn)
1、通過Link組件跳轉(zhuǎn)
import React from 'react'
import {Link} from 'react-router-dom'
export default function Login() {
?return (
? ?<div>
? ? ? ?<h1>用戶登錄</h1>
? ? ? ?<Link to="/register">沒有賬號,去注冊</Link>
? ?</div>
)
}
2、編程式路由跳轉(zhuǎn)
實現(xiàn)步驟
-
導(dǎo)入useNavigate鉤子函數(shù)
import {useNavigate} from 'react-router-dom'
-
執(zhí)行鉤子函數(shù)得到跳轉(zhuǎn)函數(shù)
let navigate=useNavigate();
-
執(zhí)行跳轉(zhuǎn)函數(shù)完成跳轉(zhuǎn)
import React from 'react'
import {useNavigate} from 'react-router-dom'
?
export default function Register() {
?const navigate=useNavigate()
?const register=(e)=>{
? ?e.preventDefault()
? ?navigate('/login')
}
?return (
? ?<div>
? ? ? ?<h1>用戶注冊</h1>
? ? ? ?<a href="#" onClick={(e)=>{register(e)}}>已注冊,去登錄</a>
? ?</div>
)
}
注意
-
如果在跳轉(zhuǎn)時不想加歷史記錄,可以添加額外參數(shù)replace為true
const register=(e)=>{
? ?e.preventDefault()
? ?navigate('/login',{replace:true})
}
四、嵌套路由
1、基礎(chǔ)配置
實現(xiàn)步驟
-
定義嵌套路由聲明
<Routes>
<Route path='/login' element={<Login/>}></Route>
<Route path='/register' element={<Register/>}></Route>
<Route path='/' element={<Home/>}>
<Route path='category' element={<Category/>}></Route>
<Route path='goods' element={<Goods/>}></Route>
</Route>
</Routes>
-
設(shè)置二級路由出口
export default function Home() {
return (
<>
<aside>
<ul>
<li><NavLink to="/categroy">分類管理</NavLink></li>
<li><NavLink to="/goods">商品管理</NavLink></li>
</ul>
</aside>
<section>
{/* 二級路由出口 */}
<Outlet></Outlet>
</section>
</>
)
}
2、默認(rèn)二級路由設(shè)置
<Routes>
<Route path='/login' element={<Login/>}></Route>
<Route path='/register' element={<Register/>}></Route>
<Route path='/' element={<Home/>}>
{/*默認(rèn)二級路由,添加index屬性,刪除掉path屬性*/}
<Route index element={<Main/>}></Route>
<Route path='category' element={<Category/>}></Route>
<Route path='goods' element={<Goods/>}></Route>
</Route>
</Routes>
3、404頁配置
應(yīng)用場景:當(dāng)所有的路徑都沒有匹配的時候顯示
語法說明:在各級路由的最后添加*
號路由作為兜底
<Routes>
<Route path='/login' element={<Login/>}></Route>
<Route path='/register' element={<Register/>}></Route>
<Route path='/' element={<Home/>}>
{/*默認(rèn)二級路由,添加index屬性,刪除掉path屬性*/}
<Route index element={<Main/>}></Route>
<Route path='category' element={<Category/>}></Route>
<Route path='goods' element={<Goods/>}></Route>
</Route>
{/*當(dāng)所有路徑都沒有匹配時渲染此路由*/}
<Route path='*' element={<NotFound/>}></Route>
</Routes>
五、路由模式
BrowserRouter模式部署在Nginx服務(wù)器上出現(xiàn)404問題的解決辦法
1、React打包
-
在index.js的
<BrowserRouter>
上添加basename屬性,比如
<BrowserRouter basename='/crem'>
<App></App>
</BrowserRouter>
-
在package.json中添加
"homepage": "."
{
"homepage": "."
}
-
在終端上執(zhí)行打包命令
yarn build
2、Nginx上部署
-
打包后會產(chǎn)生一個build文件夾,然后將該文件改名為crem,
-
上傳文件的linux服務(wù)器的/opt目錄下
-
在/etc/nginx/conf.d/default.conf下添加如下配置
location /crem {
alias /opt/crem;
index index.html;
}
-
進(jìn)入shell中執(zhí)行如下命令
ps aux|grep nginx #查看nginx進(jìn)程
killall -9 nginx #殺死nginx進(jìn)程
/usr/sbin/nginx #啟動nginx服務(wù)器
3、防止404的配置
-
修改/etc/nginx/conf.d/default.conf文件,添加如下配置即可
location /crem {
alias /opt/crem;
index index.html;
try_files $uri /crem/index.html;
}
六、路由傳參
1、searchParams傳參
實現(xiàn)步驟
-
傳參
import {useNavigate} from 'react-router-dom'
export default function CategroyList() {
let navigate=useNavigate();
return (
<div>
<h2>CategroyList</h2>
<button onClick={()=>{navigate('/categroyDetail?id=12')}}>詳情</button>
</div>
)
}
-
獲取參數(shù)
import {useSearchParams} from 'react-router-dom'
export default function CategoryDetail() {
let [params]=useSearchParams()
return (
<div>
<h2>CategroyDetail</h2>
<div>
ID:{params.get('id')}
</div>
</div>
)
}
2、params傳參
實現(xiàn)步驟
-
路由設(shè)置
<BrowserRouter>
<Routes>
<Route path='/home' element={<Layout/>}>
<Route path='categroy-detail/:id' element={<CategoryDetail/>}></Route>
</Route>
</Routes>
</BrowserRouter>
-
傳參
import {useNavigate} from 'react-router-dom'
export default function CategroyList() {
let navigate=useNavigate();
return (
<div>
<h2>CategroyList</h2>
<button onClick={()=>{navigate('/home/categroy-detail/13')}}>詳情</button>
</div>
)
}
-
獲取參數(shù)
import React from 'react'
import {useParams} from 'react-router-dom'
export default function CategoryDetail() {
let params=useParams()
return (
<div>
<h2>CategroyDetail</h2>
<div>
ID:{params.id}
</div>
</div>
)
}
七、集中式路由渲染
實現(xiàn)步驟
-
在項目根目錄創(chuàng)建router文件夾,并在該目錄下創(chuàng)建index.jsx
-
在router/index.jsx編寫路由配置項
import Login from '../pages/Login'
import Register from '../pages/Register'
import Home from '../pages/Home'
import CategoryList from '../pages/Category'
import CategoryDetail from '../pages/Category/Detail'
import GoodsList from '../pages/Goods'
import Main from '../pages/Home/Main'
export default [
{
path:'/login',
element:<Login/>
},
{
path:'/register',
element:<Register/>
},
{
path:'/',
element:<Home/>,
children:[
{
index:true,
element:<Main/>
},
{
path:'/categoryList',
element:<CategoryList/>
},
{
path:'/categoryDetail/:id',
element:<CategoryDetail/>
},
{
path:'/goodsList',
element:<GoodsList/>
}
]
}
]
-
在App.jsx中通過useRoutes鉤子函數(shù)來進(jìn)行集中式配置
import {useRoutes} from 'react-router-dom'
import router from './router/index'
function App() {
return useRoutes(router)
}
export default App;
-
在項目根目錄下的index.js中使用
<BrowserRouter>
包裹<App>
root.render(
<BrowserRouter>
<App/>
</BrowserRouter>
)
八、路由懶加載
1、實現(xiàn)步驟
-
使用lazy(()=>import('xxx'))方式導(dǎo)入組件
import {lazy} from 'react'
const Login=lazy(()=>import('../pages/Login'))
const Register=lazy(()=>import('../pages/Register'))
const Home=lazy(()=>import('../pages/Home'))
const CategoryList=lazy(()=>import('../pages/Category'))
const CategoryDetail=lazy(()=>import('../pages/Category/Detail'))
const GoodsList=lazy(()=>import('../pages/Goods'))
const Main=lazy(()=>import('../pages/Home/Main'))
export default [
{
path:'/login',
element:<Login/>
},
{
path:'/register',
element:<Register/>
},
{
path:'/',
element:<Home/>,
children:[
{
index:true,
element:<Main/>
},
{
path:'/categoryList',
element:<CategoryList/>
},
{
path:'/categoryDetail/:id',
element:<CategoryDetail/>
},
{
path:'/goodsList',
element:<GoodsList/>
}
]
}
]
-
通過 React 中提供了
<Suspense>
組件,來實現(xiàn)路由的懶加載。
import {Suspense} from 'react'
function App() {
return(
<Suspense fallback={<>loading</>}>
{useRoutes(router)}
</Suspense>
)
}
<Suspense>
組件身上,必須設(shè)置一個 fallback
屬性,屬性值可以是一個 HTML 標(biāo)簽,也可以是一個自定義的組件。用于當(dāng)路由組件還未加載出來前的提示。
2、解決路由閃屏
配置完路由懶加載后出現(xiàn)當(dāng)進(jìn)行路由跳轉(zhuǎn)時,出現(xiàn)閃屏現(xiàn)象,要向解決這個問題可以使用 react-loadable插件進(jìn)行解決
-
先下載react-loadable依賴包
yarn add react-loadable
-
建立一個loadable.js,放在src/utils/loadable.js文章來源:http://www.zghlxwxcb.cn/news/detail-694479.html
import Loadable from 'react-loadable';
export default function withLoadable(comp) {
return Loadable({
//懶加載組件頁面
loader: comp,
loading: () => null,
delay: "",
})
}
-
修改router/index.js文章來源地址http://www.zghlxwxcb.cn/news/detail-694479.html
import loadable from '../utils/loadable'
const Login=loadable(()=>import('../pages/Login'))
const Register=loadable(()=>import('../pages/Register'))
const Home=loadable(()=>import('../pages/Home'))
const CategoryList=loadable(()=>import('../pages/Category'))
const CategoryDetail=loadable(()=>import('../pages/Category/Detail'))
const GoodsList=loadable(()=>import('../pages/Goods'))
const Main=loadable(()=>import('../pages/Home/Main'))
export default [
{
path:'/login',
element:<Login/>
},
{
path:'/register',
element:<Register/>
},
{
path:'/',
element:<Home/>,
children:[
{
index:true,
element:<Main/>
},
{
path:'/categoryList',
element:<CategoryList/>
},
{
path:'/categoryDetail/:id',
element:<CategoryDetail/>
},
{
path:'/goodsList',
element:<GoodsList/>
}
]
}
]
到了這里,關(guān)于React筆記(六)React路由的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!