React-Router的使用

申明式声明路由 

         <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 会调用 pushState 或 replaceState 方法来更新浏览器的地址栏,而不重新加载页面。
  • 处理历史记录: 当用户使用浏览器的前进或后退按钮时,popstate 事件会被触发。React Router 会监听这个事件,并根据新的 URL 更新渲染的组件。

Routes

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

Route

默认路由 

<Route index element={<Homepage />} />

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

定义路由 

<Route path="product" element={<Product />} />
<Route path="pricing" element={<Pricing />} />
<Route path="login" element={<Login />} />

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

受保护的路由 

<Route
  path="app"
  element={
    <ProtectedRoute>
      <AppLayout />
    </ProtectedRoute>
  }
>

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


<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 />} />

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

注意: 嵌套路由的时候需要使用<Outlet>当作占位符来根据不同的url选择性渲染不同的组件。

Navigate组件

<Route index element={<Navigate replace to="cities" />} />

作用

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

属性

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

使用场景

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

路由参数

<Route path="cities/:id" element={<City />} />

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

具体解释

  1. 动态参数:
    • :id 是一个占位符,用于匹配 URL 中的特定部分。当用户访问类似 /cities/1 或 /cities/42 的 URL 时,:id 将匹配到 1 或 42,并将其作为参数传递给相应的组件。
  2. 访问参数:
    • 在 City 组件中,可以使用 React Router 提供的 useParams 钩子来获取这个动态参数。例如:
      import { useParams } from "react-router-dom";  
      function City() {
          const { id } = useParams();
          ...
      }
      
    • 这样,当用户访问 /cities/1 时,id 的值将为 1,而当访问 /cities/42 时,id 的值将为 42

useParam vs useSearchParam

 前者对应蓝色部分,后者对应黄色部分,搜索参数是?之后的值在网址中。

404错误

 <Route path="*" element={<PageNotFound />} />

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

Navigating

NavLink

该组件用于需要呈现active状态的导航链接。

每当NavLink处于活动状态时,它都会自动具有一个.active类名,以便使用 CSS 轻松设置样式:

a.active {
  color: red;
}

当然如果要在 css module中使用的话,还得设置为全局变量:

/* CSS Modules feature */
.nav a:global(.active) {
  background-color: var(--color-dark--0);
}

 它还在className 、 style和具有活动状态的children上提供回调属性,用于内联样式或条件渲染:

// className
<NavLink
  to="/messages"
  className={({ isActive }) =>
    isActive ? "text-red-500" : "text-black"
  }
>
  Messages
</NavLink>
// style
<NavLink
  to="/messages"
  style={({ isActive }) => ({
    color: isActive ? "red" : "black",
  })}
>
  Messages
</NavLink>
// children
<NavLink to="/message">
  {({ isActive }) => (
    <span className={isActive ? "active" : ""}>
      {isActive ? "👉" : ""} Tasks
    </span>
  )}
</NavLink>

Link 

当链接不需要活动样式时使用<Link> 

useNavigate

该钩子允许程序员将用户导航到新页面,而无需用户交互。对于正常导航,最好使用LinkNavLink 。它们提供更好的默认用户体验,例如键盘事件、辅助功能标签、“在新窗口中打开”、右键单击上下文菜单等。

保留使用useNavigate到用户没有交互但需要导航的情况,例如:

  • 表单提交完成后
  • 不活动后将其注销
  • 定时 UI,例如测验等。

useNavigate与useSearchParmas

const navigate = useNavigate()

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值