React中路由的參數傳遞路由的配置文件詳解
路由的參數傳遞
傳遞參數有二種方式(需要註意的是, 這兩種方式在Router6.x中都是提供的hook函數的API, 類組件需要通過高階組件的方式使用):
動態路由的方式;
search傳遞參數(查詢字符串);
方式一: 動態路由的概念指的是路由中的路徑並不會固定:
比如/detail的path對應一個組件Detail;
如果我們將path在Route匹配時寫成/detail/:id,那麼 /detail/111、/detail/123都可以匹配到該Route,並且進行顯示;
這個匹配規則,我們就稱之為動態路由;
通常情況下,使用動態路由可以為路由傳遞參數。
配置動態路由
render() { return ( <div className='app'> <div className='header'> <Link to="detail/123">詳情123</Link> <Link to="detail/321">詳情321</Link> <Link to="detail/aaa">詳情aaa</Link> </div> <div className='counter'> <Routes> <Route path='/detail/:id' element={<Detail/>}/> </Routes> </div> <div className='footer'>footer</div> </div> ) }
在跳轉的頁面中可以通過hook函數useParms獲取到傳入的id, 由於我們現在使用的是類組件, 無法使用hook函數, 因此需要通過高階組件對當前組件增強(上一篇剛剛講過高階組件的封裝, 這裡直接使用, 給到大傢代碼)
import { useNavigate, useParams } from "react-router-dom" export default function withRouter(WrapperComponent) { return function(props) { const naviagte = useNavigate() const params = useParams() const router = {naviagte, params} return <WrapperComponent {...props} router={router} /> } }
使用高階組件增強當前Detail組件, 就可以通過useParams獲取到傳遞的id
import React, { PureComponent } from 'react' import withRouter from '../hoc/with_router' export class Detail extends PureComponent { render() { // 獲取到params const { params } = this.props.router return ( <div> <h2>Detail</h2> {/* 通過params獲取到id並展示 */} <h2>id: {params.id}</h2> </div> ) } } export default withRouter(Detail)
方式二: search傳遞參數(也就是查詢字符串的方式), 這裡在User組件中進行演示
在路由跳轉時拼接上查詢字符串
render() { return ( <div className='app'> <div className='header'> <Link to="/user?name=chenyq&age=18&height=1.88">用戶</Link> </div> <div className='counter'> <Routes> <Route path='/user' element={<User/>} /> </Routes> </div> <div className='footer'>footer</div> </div> ) }
查詢字符串需要通過hook函數useSearchParams獲取, 所以我們也需要使用高階組件對User組件進行增強
// 封裝的高階組件 import { useNavigate, useParams, useSearchParams } from "react-router-dom" export default function withRouter(WrapperComponent) { return function(props) { // 1.導航 const naviagte = useNavigate() // 2.動態路由的參數 const params = useParams() // 3.查詢字符串的參數 const [searchParams] = useSearchParams() const query = Object.fromEntries(searchParams.entries) const router = {naviagte, params, query} return <WrapperComponent {...props} router={router} /> } }
在組件中就可以獲取到參數
import React, { PureComponent } from 'react' import withRouter from '../hoc/with_router' export class User extends PureComponent { render() { // 獲取高階組件中的query const { query } = this.props.router return ( <div> <h2>User</h2> {/* 通過query獲取參數 */} <h2>參數: {query.name}-{query.age}-{query.height}</h2> </div> ) } } export default withRouter(User)
路由的配置文件
目前我們所有的路由定義都是直接使用Route組件,並且添加屬性來完成的。
但是這樣的方式會讓路由變得非常混亂,我們希望像vue-router那樣, 將所有的路由配置放到一個單獨的文件進行集中管理:
在早期的時候,Router並且沒有提供相關的API,我們需要借助於react-router-config完成;
在Router6.x中,為我們提供瞭useRoutes API可以完成相關的配置;
例如我們將下面的映射關系配置到一個單獨的文件中
<div className='counter'> <Routes> {/* 當默認路徑 / 時, 重定向到home頁面 */} <Route path='/' element={<Navigate to="/home"/>}></Route> {/* 配置二級路由 */} <Route path='/home' element={<Home/>}> <Route path='/home' element={<Navigate to="/home/recommend"/>}/> <Route path='/home/recommend' element={<HomeRecommend/>}/> <Route path='home/ranking' element={<HomeRanking/>}/> </Route> <Route path='/about' element={<About/>}/> <Route path='/profile' element={<Profile/>}/> <Route path='/category' element={<Category/>}/> <Route path='/order' element={<Order/>}/> <Route path='/detail/:id' element={<Detail/>}/> <Route path='/user' element={<User/>} /> {/* 當上面路徑都沒有匹配到時, 顯式Notfound組件 */} <Route path='*' element={<Notfound/>}/> </Routes> </div>
首先, 使用useRoutes這個API替代原來的Routes和Route組件, useRoutes可以當成一個函數直接使用, 但是隻能在函數組件中使用
<div className='counter'> {useRoutes(routes)} </div>
再在route/index.js中對映射關系進行配置
import { Navigate } from "react-router-dom" import Home from '../pages/Home' import About from '../pages/About' import Profile from '../pages/Profile' import Notfound from '../pages/Notfound' import HomeRecommend from '../pages/HomeRecommend' import HomeRanking from '../pages/HomeRanking' import Category from '../pages/Category' import Order from '../pages/Order' import Detail from '../pages/Detail' import User from '../pages/User' const routes = [ { path: "/", element: <Navigate to="/home"/> }, { path: "/home", element: <Home/>, children: [ { path: "/home", element: <Navigate to="/home/recommend" /> }, { path: "/home/recommend", element: <HomeRecommend/> }, { path: "/home/ranking", element: <HomeRanking/> } ] }, { path: "/about", element: <About/> }, { path: "/profile", element: <Profile/> }, { path: "/category", element: <Category/> }, { path: "/order", element: <Order/> }, { path: "detail/:id", element: <Detail/> }, { path: "/user", element: <User/> }, { path: "*", element: <Notfound/> } ] export default routes
如果我們對某些組件進行瞭異步加載(懶加載, 分包處理),那麼需要使用Suspense進行包裹:
例如我們對Detail和User進行懶加載(分包處理)
// import Detail from '../pages/Detail' // import User from '../pages/User' const Detail = React.lazy(() => import("../pages/Detail")) const User = React.lazy(() => import("../pages/User"))
並且還需要使用Suspense對組件進行包裹
root.render( <HashRouter> <Suspense fallback={<h3>loading</h3>}> <App/> </Suspense> </HashRouter> )
到此這篇關於React中路由的參數傳遞 – 路由的配置文件的文章就介紹到這瞭,更多相關React路由參數傳遞內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- React-Router6版本的更新引起的路由用法變化
- Vue路由router詳解
- vuejs路由的傳參及路由props配置詳解
- 使用React Router v6 添加身份驗證的方法
- react-router-domV6版本的路由和嵌套路由寫法詳解