概念介绍

React是一个库。包含的核心内容:JSX+组件
React官方并没有提供我们需要的路由模块。推荐使用第三方的路由模块React-Router(组件)。
ReactRouter也是组件,我们下载这个插件,引入对应的路由组件。搭建我们的路由

  1. Vue的路由称为配置式路由。将所有路由信息放在js文件中。提供一个渲染出口就可以
  2. ReactRouter提供的路由编程式路由,我们需要在哪个地方使用路由,代码就写在那个组件中
  3. 约定式路由,按照约定的目录来设计组件或者页面,自动生成路由。umijs

    基础使用

    安装

    1. yarn add react-router-dom@6

    介绍

    路由模式

    分为BrowserRouterHashRouter两种模式
    使用时都是包裹整个应用,一个 React 应用只需要使用一次
  • BrowserRouter
  • HashRouter

  • 用于指定导航链接,完成路由跳转

  • 组件通过to属性指定路由地址,最终会渲染为a链接元素

    Routes

    提供一个路由出口,满足条件的路由组件会渲染到组件内部,定义path和组件的对应关系

    Route

  • 用于指定导航链接,完成路由匹配

  • path属性指定匹配的路径地址,element属性指定要渲染的组件

    配置路由

    ```javascript import React from ‘react’ import { BrowserRouter, HashRouter, Routes, Route, Navigate } from ‘react-router-dom’

import Login from ‘./Login’; import Reg from ‘./Reg’; import Home from ‘./Home’; import NotFound from ‘./NotFound’; import Person from ‘./Person’; import Goods from ‘./Goods’; export default function RouterContainer () { return ( // /Navigate组件在这里用作重定向 } /> } /> } /> } /> }> // //当浏览器地址栏输入的url没有匹配到配置的路由时,渲染NotFound组件 } /> ) }

  1. <a name="ZB00G"></a>
  2. ### 配置嵌套路由
  3. 1. 在需要嵌套二级路由的`Route`下嵌套`Route`路由,注意`path`前面不要加`/`
  4. 2. 在需要嵌套二级路由组件里引入`Outlet`钩子
  5. 3. 配置路由出口`<Outlet />`
  6. 4. 访问`/一级路由/二级路由` `http://localhost:5173/home/person`
  7. ```javascript
  8. import React from 'react'
  9. import { BrowserRouter, HashRouter, Routes, Route, Navigate } from 'react-router-dom'
  10. import Login from './Login';
  11. import Reg from './Reg';
  12. import Home from './Home';
  13. import NotFound from './NotFound';
  14. import Person from './Person';
  15. import Goods from './Goods';
  16. export default function RouterContainer () {
  17. return (
  18. <BrowserRouter>
  19. <Routes>
  20. // /Navigate组件在这里用作重定向
  21. <Route path="/" element={<Navigate to="/home" replace />} />
  22. <Route path="/login/:id" element={<Login />} />
  23. <Route path="/login" element={<Login />} />
  24. <Route path="/reg" element={<Reg />} />
  25. <Route path="/home" element={<Home />}>
  26. <Route path="person" element={<Person />} />
  27. <Route path="goods" element={<Goods />} />
  28. </Route>
  29. // 当浏览器地址栏输入的url没有匹配到配置的路由时,渲染NotFound组件
  30. <Route path="*" element={<NotFound />} />
  31. </Routes>
  32. </BrowserRouter>
  33. )
  34. }
  1. import React from 'react'
  2. import { Outlet } from 'react-router-dom'
  3. import './home.scss'
  4. export default function Home () {
  5. return (
  6. <div className='home'>
  7. <div className='left'>
  8. <div>人员管理</div>
  9. <div>商品管理</div>
  10. </div>
  11. <div className='right'>
  12. {/**路由出口 */}
  13. <Outlet />
  14. </div>
  15. </div>
  16. )
  17. }

Index Route

如果跳转到/home的时候还想做一个重定向,或者渲染一个默认内容,则可以使用Index Route

  1. import React from 'react'
  2. import { BrowserRouter, HashRouter, Routes, Route, Navigate } from 'react-router-dom'
  3. import Login from './Login';
  4. import Reg from './Reg';
  5. import Home from './Home';
  6. import NotFound from './NotFound';
  7. import Person from './Person';
  8. import Goods from './Goods';
  9. export default function RouterContainer () {
  10. return (
  11. <BrowserRouter>
  12. <Routes>
  13. // /Navigate组件在这里用作重定向
  14. <Route path="/" element={<Navigate to="/home" replace />} />
  15. <Route path="/login/:id" element={<Login />} />
  16. <Route path="/login" element={<Login />} />
  17. <Route path="/reg" element={<Reg />} />
  18. <Route path="/home" element={<Home />}>
  19. <Route index
  20. element={<div>`/home`路径的默认内容,也可以单独封装一个组件</div>} />
  21. <Route path="person" element={<Person />} />
  22. <Route path="goods" element={<Goods />} />
  23. </Route>
  24. // //当浏览器地址栏输入的url没有匹配到配置的路由时,渲染NotFound组件
  25. <Route path="*" element={<NotFound />} />
  26. </Routes>
  27. </BrowserRouter>
  28. )
  29. }

当父路由被匹配,但是子路由没有被匹配的时候,Index Route会被匹配,即:Index Route对应的element会被渲染出来

路由跳转

通过Link或者NavLink组件跳转

如果在跳转时不想加历史记录,可以添加额外参数replace为true

  1. import {Link,NavLink} from 'react-router-dom'
  2. <Link to="/login" replace>Link跳转到登录</Link>
  3. <NavLink to="/login" replace>NavLink跳转到登录</NavLink>

通过js跳转

  1. import React from 'react';
  2. import {useNavigate} from 'react-router-dom';
  3. export default function AddAccount() {
  4. const navigate = useNavigate();
  5. function goToLogin(){
  6. navigate("/login");
  7. }
  8. return (
  9. <div>Goods <button onClick={goToLogin}>跳转到登录</button></div>
  10. )
  11. }

路由传参

url parmas

  1. Route组件匹配的path中加上动态路由 path='/xxx/:id'
  2. navigate跳转路由后加上参数navigate('/xxx/参数')
  3. 在跳转组件中引入useParams钩子
  4. 调用 useParams赋值给 params
  5. params对象中可以获取到对应参数

假设/reg路径需要接受一个参数,则在路由配置登录路径的时候,要做如下处理

  1. <BrowserRouter>
  2. <Routes>
  3. <Route path="/" element={<Navigate to="home" replace />} />
  4. {/* 动态路由接收参数 */}
  5. <Route path="/login/:id" element={<Login />}></Route>
  6. </Routes>
  7. </BrowserRouter>

跳转的时候传递参数

  1. import { useNavigate } from 'react-router-dom'
  2. function Home () {
  3. // 只能够在函数组件的根部调用,不可以放在条件语句或者某个自定义函数内部去调用
  4. const navigate = useNavigate()
  5. const toLogin = () => {
  6. // 直接在path后面加参数
  7. navigate('/login/1001')
  8. }
  9. return (
  10. <div>Home
  11. <button onClick={toLogin}>去Login</button>
  12. </div>
  13. )
  14. }
  15. export default Home

获取路由参数

  1. // 引入 useParams 钩子
  2. import { useParams } from 'react-router-dom'
  3. function Login () {
  4. // 调用 useParams 赋值给 params
  5. const params = useParams()
  6. return (
  7. <div>
  8. {/* 使用传来的参数 */}
  9. params参数{params.id}
  10. </div>
  11. )
  12. }
  13. export default Login
  1. import React, { Component } from 'react'
  2. export default class Login extends Component {
  3. render(){
  4. // 接收params参数
  5. console.log(this.props.match.params)
  6. }
  7. }

searchParams

  1. 引入 useSearchParams钩子
  2. 调用 useSearchParams函数,通过结构赋值拿到 params对象
  3. 调用 params对象的 get方法,将要获取的路由参数作为实参传入 ```javascript import { useNavigate } from ‘react-router-dom’ function Login () { const navigate = useNavigate() const toAbout = () => { navigate(‘/about?id=1001&name=loveZero’) } return (
    Login
    ) }

export default Login

  1. 接收参数
  2. ```javascript
  3. // 引入 useSearchParams 钩子
  4. import { useSearchParams } from 'react-router-dom'
  5. function About () {
  6. // 调用 useSearchParams 函数,通过结构赋值拿到 params 对象
  7. const [params] = useSearchParams()
  8. // 调用 params 对象的 get 方法,将要获取的路由参数作为实参传入
  9. let id = params.get('id')
  10. let name = params.get('name')
  11. return (
  12. <div>About---{id}---{name}</div>
  13. )
  14. }
  15. export default About
  1. import React, { Component } from 'react'
  2. //获取到的search是urlencoded编码字符串,需要借助querystring解析
  3. import qs from 'querystring'
  4. let obj = { id: 1, name: 'mingming' }
  5. console.log(qs.stringify(obj)) // id=1&name=mingming 这是urlencoded格式
  6. let query = 'id=1&name=mingming'
  7. console.log(qs.parse(query)) // {id: "1", name: "mingming"}
  8. export default class About extends Component {
  9. render(){
  10. // 接收search参数
  11. console.log(this.props.location.search)
  12. }
  13. }

路由懒加载

通过react自带的方法 React.lazyReact.Suspense实现(推荐的方式)
以登录、注册和首页为例

  1. 所有需要懒加载的组件都要使用React.lazy处理一次,返回一个新的组件
  2. React.Suspense可以指定加载指示器(loading indicator),懒加载的组件必须位于React.Suspense下方
    1. import React from 'react';
    2. import { BrowserRouter, Routes, Route } from 'react-router-dom';
    3. const Login = React.lazy(() => import("./pages/Login"));
    4. const Reg = React.lazy(() => import("./pages/Reg"));
    5. const Home = React.lazy(() => import("./pages/Home"));
    6. const NotFound = React.lazy(() => import("./pages/NotFound"));
    7. function App () {
    8. return (
    9. <React.Suspense fallback={<div>加载中...</div>}>
    10. <BrowserRouter>
    11. <Routes>
    12. <Route path="/" element={<Navigate to="home" replace />} />
    13. <Route path="/login" element={<Login />}></Route>
    14. <Route path="reg" element={<Reg />} />
    15. <Route path="home" element={<Home />} />
    16. <Route path="*" element={<NotFound />} />
    17. </Routes>
    18. </BrowserRouter>
    19. </React.Suspense>
    20. );
    21. }
    22. export default App;

    配置式路由useRoutes

    ReactRouter默认提供的是路由编程式路由,也可以采用配置式路由的方式
    useRoutes只能在BrowserRouter或者HashRouter的子组件中使用 ```javascript import React from ‘react’ import { BrowserRouter } from ‘react-router-dom’

import MyRouters from ‘./MyRouter.jsx’ export default function RouterContainer () { return ( loading}> ) }

  1. ```javascript
  2. import React from 'react'
  3. import { Navigate, useRoutes } from "react-router-dom"
  4. import Login from './Login';
  5. import Reg from './Reg';
  6. import Home from './Home';
  7. import NotFound from './NotFound';
  8. import Person from './Person';
  9. import Goods from './Goods';
  10. const routes = [
  11. {
  12. path: '/',
  13. element: <Navigate to="/home" />
  14. },
  15. {
  16. path: "/login/:code",
  17. element: <Login />
  18. },
  19. {
  20. path: "/login",
  21. element: <Login />
  22. },
  23. {
  24. path: "/reg",
  25. element: <Reg />
  26. },
  27. {
  28. path: "/home",
  29. element: <Home />,
  30. children: [
  31. {
  32. index: true,
  33. element: <div>`/home`路径的默认内容,也可以单独封装一个组件</div>,
  34. },
  35. {
  36. path: "person",
  37. element: <Person />,
  38. },
  39. {
  40. path: "goods",
  41. element: <Goods />
  42. }
  43. ]
  44. },
  45. {
  46. path: "*",
  47. element: <NotFound />
  48. }
  49. ]
  50. export default function MyRouters () {
  51. const element = useRoutes(routes)
  52. return element
  53. }