React-Route的使用

javascript 复制代码
         <BrowserRouter>
            <Routes>
              <Route index element={<Homepage />} />
              <Route path="product" element={<Product />} />
              <Route path="pricing" element={<Pricing />} />
              <Route path="login" element={<Login />} />
              <Route
                path="app"
                element={
                  <ProtectedRoute>
                    <AppLayout />
                  </ProtectedRoute>
                }
              >
                <Route index element={<Navigate replace to="cities" />} />
                <Route path="cities" element={<CityList />} />
                <Route path="cities/:id" element={<City />} />
                <Route path="countries" element={<CountryList />} />
                <Route path="form" element={<Form />} />
              </Route>
              <Route path="*" element={<PageNotFound />} />
            </Routes>
          </BrowserRouter>

BrowserRouter

BrowserRouter 是 React Router 提供的一个组件,利用 HTML5 的历史 API 来保持用户界面(UI)与 URL 的同步。下面详细解释这一机制是如何实现的。

实现原理

1. HTML5 History API

BrowserRouter 主要依赖于 HTML5 的 history 对象,该对象提供了以下几个重要方法:

  • pushState(state, title, url): 这个方法用于向浏览器的历史记录中添加一个新的条目。调用此方法后,URL 将更新,但页面不会重新加载。
  • replaceState(state, title, url) : 此方法与 pushState 类似,但它替换当前的历史记录条目,而不是添加新的条目。
  • popstate 事件 : 当用户点击浏览器的前进或后退按钮时,会触发 popstate 事件。这允许应用程序检测到 URL 的变化并作出相应的反应。

2. URL 与 UI 的同步

当使用 BrowserRouter 时,React Router 会监听 URL 的变化,并根据当前的 URL 渲染相应的组件。具体步骤如下:

  • 初始化 : 当应用程序加载时,BrowserRouter 会读取当前的 URL,并根据路由配置渲染相应的组件。
  • 用户交互 : 当用户通过点击链接(例如使用 <Link> 组件)进行导航时,React Router 会调用 pushStatereplaceState 方法来更新浏览器的地址栏,而不重新加载页面。
  • 处理历史记录 : 当用户使用浏览器的前进或后退按钮时,popstate 事件会被触发。React Router 会监听这个事件,并根据新的 URL 更新渲染的组件。

Routes

Routes 是一个容器,用于定义应用程序中的所有路由。它会根据当前 URL 渲染相应的 Route 组件。

Route

默认路由

javascript 复制代码
<Route index element={<Homepage />} />

该Route 定义了一个特定路径的组件。这里的 index 属性表示当用户访问根路径时(例如 /),将渲染 Homepage 组件。

定义路由

javascript 复制代码
<Route path="product" element={<Product />} />
<Route path="pricing" element={<Pricing />} />
<Route path="login" element={<Login />} />

这些Route 元素指定了一个URL 路径和对应的组件。当用户访问这些路径时,会渲染相应的组件。例如,访问 /product 时会显示 Product 组件。

受保护的路由

javascript 复制代码
<Route
  path="app"
  element={
    <ProtectedRoute>
      <AppLayout />
    </ProtectedRoute>
  }
>

这个路由使用了一个名为 ProtectedRoute 的组件,通常用于保护某些页面,确保只有经过身份验证的用户才能访问。在这个例子中,只有在通过 ProtectedRoute 验证后,才能访问包含在 AppLayout 中的子路由。


javascript 复制代码
<Route index element={<Navigate replace to="cities" />} />
<Route path="cities" element={<CityList />} />
<Route path="cities/:id" element={<City />} />
<Route path="countries" element={<CountryList />} />
<Route path="form" element={<Form />} />

这些路由是上面路由的子路由。

javascript 复制代码
<Route index element={<Navigate replace to="cities" />} />

作用

  • 重定向 : <Navigate> 组件用于将用户从一个路由重定向到另一个路由。在这个例子中,它将用户重定向到 cities 路径。

属性

  • to : 这是目标路径,表示用户将被重定向到哪里。在这个例子中,to="cities" 表示用户将被重定向到 /cities 路径。
  • replace : 这是一个布尔属性,如果设置为 true,则会使用 history.replace() 方法来替换当前的历史记录条目,而不是添加新的条目。这意味着用户在浏览器中点击"后退"按钮时,不会返回到重定向前的页面。

使用场景

  • 条件导航: 在某些情况下,例如用户未登录时,可能希望将他们重定向到登录页面;或者在访问某个页面后立即重定向到另一个页面。
  • 默认路由 : 在嵌套路由中,可以使用 <Navigate> 来设置默认路由。例如,在访问 /app 时,可以立即重定向到 /app/cities

动态路由

javascript 复制代码
<Route path="cities/:id" element={<City />} />

id 是一个动态参数,它表示在访问该路由时,URL 中的具体值将被捕获并传递给渲染的组件。

具体解释

  1. 动态参数 :
    • :id 是一个占位符,用于匹配 URL 中的特定部分。当用户访问类似 /cities/1/cities/42 的 URL 时,:id 将匹配到 142,并将其作为参数传递给相应的组件。
  2. 访问参数 :
    • City 组件中,可以使用 React Router 提供的 useParams 钩子来获取这个动态参数。例如:

      javascript 复制代码
      import { useParams } from "react-router-dom";  
      function City() {
          const { id } = useParams();
          ...
      }
    • 这样,当用户访问 /cities/1 时,id 的值将为 1,而当访问 /cities/42 时,id 的值将为 42

404错误

javascript 复制代码
 <Route path="*" element={<PageNotFound />} />

使用 path="*" 匹配所有未定义的路径,并渲染 PageNotFound 组件。这是处理404错误页面的常见方式。

补充:

javascript 复制代码
const navigate = useNavigate()

navigate(`form?lat=${e.latlng.lat}&lng=${e.latlng.lng}`);
javascript 复制代码
  const [searchParams] = useSearchParams();
  const lat = searchParams.get("lat");
  const lng = searchParams.get("lng");

通过这种方式可以实现再URL存储传递全局state

相关推荐
即将头秃的程序媛1 分钟前
vue 项目实现阻止浏览器记住密码
前端·javascript·vue.js
李豆豆喵2 分钟前
第31天:安全开发-JS应用&WebPack打包器&第三方库JQuery&安装使用&安全检测
javascript·webpack·jquery
Williamoses2 分钟前
elementui table滚动分页加载
前端·vue.js·elementui
时光匆匆岁月荏苒,转眼我们已不是当年3 分钟前
【VUE小型网站开发】优化通用配置 二
前端·javascript·vue.js
Serenity_Qin4 分钟前
vue3 + ts 使用 el-tree
前端·vue.js·typescript·vue3·element-plus
fury_1231 小时前
当大的div中有六个小的div,上面三个下面三个,当外层div高变大的时候我希望里面的小的div的高也变大
前端·javascript·html
大鸡腿最好吃1 小时前
为啥react要用jsx
前端·javascript·react.js
小黄编程快乐屋1 小时前
前端小练习——大雪纷飞(JS没有上限!!!)
开发语言·前端·javascript
程序猿阿伟1 小时前
《平衡之策:C++应对人工智能不平衡训练数据的数据增强方法》
前端·javascript·c++
STUPID MAN1 小时前
vue3使用后端传递的文件流进行文件预览
前端·javascript·vue.js·文件预览