React-路由

1、安装

npm install react-router-dom

2、传统路由(组件式路由)

  • 核心组件<BrowserRouter> + <Routes> + <Route>

  • 特点

    • 路由通过 JSX 组件树直接定义
    • 数据加载(如 API 请求)通常在组件内部(如 useEffect)处理
    • 适用于简单应用,无需复杂数据预加载的场景
  • 示例

// App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Login from "./page/Login"
import Article from "./page/Article"
import ErrorPage from "../page/ErrorPage"

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Login />} /> {/* 匹配默认路由 */}
        <Route path="/login" element={<Login />} />
        <Route path="/about" element={<Article />} />
        <Route path="*" element={<ErrorPage />} /> {/* 匹配所有未知路径 */}
      </Routes>
    </BrowserRouter>
  );
}

export default App
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import store from './store'
import { Provider } from 'react-redux'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
)

3、数据路由(Data Router)

  • 核心 APIcreateBrowserRouter + RouterProvider

  • 特点

    • 集中式路由配置:通过 JavaScript 对象定义路由,而非 JSX
    • 内置数据流:支持路由级的 loader(数据预加载)和 action(表单提交处理)
    • 错误边界:可通过 errorElement 统一处理路由级错误
    • 适用于需要复杂数据预加载、服务端渲染(SSR)或静态生成(SSG)的场景
  • 示例

// src/router/index.js
import { createBrowserRouter } from 'react-router-dom'
import Login from "../page/Login"
import Article from "../page/Article"
import ErrorPage from "../page/ErrorPage"

const router = createBrowserRouter([
  {
    path: "/", // 匹配默认路由
    element: <Login />,
    errorElement: <ErrorPage />, // 404路由配置方法一
  },
  // { // 404路由配置方法二
  //  path: "*",
  //  element: <ErrorPage />
  // },
  {
    path: "/login",
    element: <Login />,
  },
  {
    path: "/article",
    element: <Article />
  }
])

export default router
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import store from './store'
import { Provider } from 'react-redux'
import { RouterProvider } from 'react-router-dom'
import router from './router'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <RouterProvider router={router} />
  </Provider>
)

总结

  • createBrowserRouter + RouterProvider 是 React Router v6.4+ 的数据路由 API,用于替代传统的 <BrowserRouter>,提供更强大的数据流控制。
  • 适用场景:需要预加载数据、统一错误处理或复杂路由逻辑的应用。
  • 与传统路由的关系:数据路由是传统路由的功能扩展,两者可结合使用,但推荐新项目直接采用数据路由

4、路由跳转

(1)声明式跳转(Link标签)

import { Link } from "react-router-dom"
function Login() {
  return (
    <div>
      <Link to="/article">跳转到文章列表</Link>
    </div>
  )
}
export default Login

(2)编程式跳转(useNavigate钩子

import { useNavigate } from "react-router-dom"
function Login() {
  const navigate = useNavigate()
  return (
    <div>
      <button onClick={() => {navigate('/article')}}>跳转到文章列表</button>
    </div>
  )
}
export default Login

5、路由传参

(1)路径参数传参(Params)

        通过 URL 路径传递参数(需提前在路由配置中定义动态段 :params)。

// 路由配置
const router = createBrowserRouter([
  {
    path: "/article/:name/:age",
    element: <Article />
  }
])

// 跳转时传递参数
navigate('/article/zhangsan/18')

// 目标组件中获取参数
import { useParams } from 'react-router-dom'
function Article() {
  const params = useParams()
  const name = params.name
  const age = params.age
  return (
    <div>文章{ name } - { age}</div>
  )
}

(2)查询参数传参(Query)

        通过 URL 的?key=value形式传递参数

// 跳转时传递参数
navigate('/article?name=zhangsan&age=18')

// 目标组件中获取参数
import { useSearchParams } from "react-router-dom"
function Article() {
  const [searchParams] = useSearchParams() 
  const name = searchParams.get('name')
  const age = searchParams.get('age')
  return (
    <div>文章{ name } - { age}</div>
  )
}

(3)状态参数传参(State)

         通过state属性传递对象(数据不会暴露在 URL 中)

// 跳转时传递参数
navigate('/article', {
  state: {
    name: 'zhangsan',
    age: 18
  }
})

// 目标组件中获取参数
import { useLocation } from "react-router-dom"
function Article() {
  const location = useLocation()
  const name = location.state.name
  const age = location.state.age
  return (
    <div>文章{ name } - { age}</div>
  )
}

6、嵌套路由

  • 使用children属性配置路由嵌套关系        
  • 使用<Outlet />组件配置二级路由渲染位置
  • 子路由的 path 无需以 / 开头,会自动与父路径拼接, 以 / 开头会覆盖父路径(不推荐)
// router/index.js
import { createBrowserRouter } from 'react-router-dom'
import Layout from "../page/Layout"
import About from "../page/About"
import Board from "../page/Board"
import ErrorPage from "../page/ErrorPage"

const router = createBrowserRouter([
  {
    path: "/", // 匹配默认路由
    element: <Layout />
  },
  {
    path: "/layout",
    element: <Layout />,
    children: [ // 嵌套路由
      {
        path: "about",
        element: <About />
      },
      {
        path: "board",
        element: <Board />
      }
    ]
  }
])

export default router
// page/Layout/index.js
import { Link, Outlet } from "react-router-dom"

function Layout() {
  return (
    <div>
      我是一级路由Layout
      <Link to='/layout/about'>关于</Link>
      <Link to='/layout/board'>面板</Link>
      <Outlet />
    </div>
  )
}

export default Layout

        配置默认二级路由

        当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,设置index属性为true

const router = createBrowserRouter([
  {
    path: "/layout",
    element: <Layout />,
    children: [ // 嵌套路由
      {
        index: true,
        // path: 'about',
        element: <About />
      },
      {
        path: "board",
        element: <Board />
      }
    ]
  }
])
// page/Layout/index.js
import { Link, Outlet } from "react-router-dom"

function Layout() {
  return (
    <div>
      我是一级路由Layout
      <Link to='/layout'>关于</Link>
      <Link to='/layout/board'>面板</Link>
      <Outlet />
    </div>
  )
}

export default Layout

7、路由模式

        各个主流框架的路由常用的路由模式有俩种,history模式和hash模式,ReactRouter分别由 createBrowerRouter createHashRouter 函数负责创建

对比维度BrowserRouterHashRouter
URL 格式http://example.com/path(无 #http://example.com/#/path(带 #
底层实现基于浏览器 History API基于 window.location.hash
SEO 友好性✅(需服务端配合)❌(哈希内容可能被忽略)
服务端配置需求✅(需配置重定向到 index.html❌(无需服务端处理)
浏览器兼容性现代浏览器所有浏览器(包括旧版 IE)
适用场景生产环境 SPA(需服务端支持)静态托管(如 GitHub Pages)
代码示例createBrowerRoutercreateHashRouter

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值