首頁  >  文章  >  web前端  >  使用 React Router v6 在 React 中實作麵包屑

使用 React Router v6 在 React 中實作麵包屑

Linda Hamilton
Linda Hamilton原創
2024-09-29 06:18:01359瀏覽

Implementing Breadcrumbs in React using React Router v6

麵包屑在網頁開發中非常重要,因為它們為用戶提供了一種方法來追蹤他們在我們網頁中的當前位置,並幫助我們的網頁導航。

在本指南中,我們將使用 React-router v6 和 Bootstrap 在 React 中實作麵包屑。

React-router v6 是 React 和 React Native 中使用的路由庫,用於在網頁或 Web 應用程式中導航。

我們的實作使用 Typescript,但它也可以輕鬆用於基於 Javascript 的專案。

設定

首先,如果尚未安裝的話,讓我們在我們的專案中安裝react-router-dom:

npm 安裝react-router-dom

或替代方案,使用紗線:

紗線添加react-router-dom

讓我們也安裝 bootstrap 來設計我們的元件:

npm 安裝引導

實現我們的元件

然後我們建立一個 Breadcrumbs.tsx 元件,它將包含麵包屑的標記,還包括確定相對於根位置的當前位置的必要邏輯。

讓我們先為組件加上一個簡單的標記:

 <div className='text-primary'>
   <nav aria-label='breadcrumb'>
      <ol className='breadcrumb'>
        <li className='breadcrumb-item pointer'>
          <span className='bi bi-arrow-left-short me-1'></span>
            Back
        </li>
      </ol>
   </nav>
</div>

該組件目前只有一個後退按鈕。讓我們為後退按鈕添加一個簡單的實現,這樣當單擊時,應該加載上一頁:

  const goBack = () => {
    window.history.back();
  };

下一步將編寫一個函數,該函數將使用 matchRoutes 函數來取得目前路由並套用轉換來過濾出與目前路由相關的所有路由。
matchRoute 接受 AgnosticRouteObject 類型的物件陣列並傳回 AgnosticRouteMatch[] | null 其中 T 是我們傳入的物件的類型。
另外要注意的是,該物件必須包含名為 path 的屬性。

讓我們先為我們的路線聲明一個介面:

export interface IRoute {
  name: string;
  path: string; //Important
}

然後讓我們聲明我們的路線:

const routes: IRoute[] = [
  {
    path: '/home',
    name: 'Home'
  },
  {
    path: '/home/about',
    name: 'About'
  },
  {
    path: '/users',
    name: 'Users'
  },
  {
    path: '/users/:id',
    name: 'User'
  },
  {
    path: '/users/:id/settings/edit',
    name: 'Edit User Settings'
  }
];

我們也宣告了一個變數來保存 useLocation 鉤子,也宣告了另一個變數來保存麵包屑的狀態:

const location = useLocation();
const [crumbs, setCrumbs] = useState<IRoute[]>([]);

接下來,讓我們實現我們的功能:

const getPaths = () => {
  const allRoutes = matchRoutes(routes, location);
  const matchedRoute = allRoutes ? allRoutes[0] : null;
  let breadcrumbs: IRoute[] = [];
  if (matchedRoute) {
    breadcrumbs = routes
      .filter((x) => matchedRoute.route.path.includes(x.path))
      .map(({ path, ...rest }) => ({
        path: Object.keys(matchedRoute.params).length
          ? Object.keys(matchedRoute.params).reduce(
              (path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string), path)
          : path,
        ...rest,
      }));
  }
  setCrumbs(breadcrumbs);
};

在這裡,我們首先取得與目前位置相符的所有路線:
const allRoutes = matchRoutes(路線, 位置);

然後我們快速檢查是否回傳任何結果,並選擇第一個:
常量匹配路由=所有路由? allRoutes[0] : null;

接下來,我們過濾掉所有與目前路由相符的路由:
routes.filter((x) =>matchedRoute.route.path.includes(x.path))

然後讓我們使用結果建立一個新數組,檢查路徑是否有參數,然後用參數值交換動態路由:

 .map(({ path, ...rest }) => ({
          path: Object.keys(matchedRoute.params).length
            ? Object.keys(matchedRoute.params).reduce(
                (path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string),
                path
              )
            : path,
          ...rest,
        }));

這確保瞭如果我們在路由中將路由聲明為 /users/:id/edit 並將 id 傳遞為 1,那麼我們將得到 /users/1/edit。

接下來,讓我們在 useEffect 中呼叫我們的函數,以便它在每次我們的位置發生變化時運行:

  useEffect(() => {
    getPaths();
  }, [location]);

完成此操作後,我們就可以在標記中使用麵包屑:

{crumbs.map((x: IRoute, key: number) =>
  crumbs.length === key + 1 ? (
    <li className='breadcrumb-item'>{x.name}</li>
      ) : (
        <li className='breadcrumb-item'>
          <Link to={x.path} className=' text-decoration-none'>
            {x.name}
          </Link>
        </li>
      )
 )}

在這裡,顯示所有的麵包屑及其鏈接,除了最後一個僅顯示名稱的麵包屑。

這樣,我們現在就有了完整的 BreadCrumbs.tsx 組件:

import { useEffect, useState } from 'react';
import { Link, matchRoutes, useLocation } from 'react-router-dom';

export interface IRoute {
  name: string;
  path: string;
}

const routes: IRoute[] = [
  {
    path: '/home',
    name: 'Home',
  },
  {
    path: '/home/about',
    name: 'About',
  },
  {
    path: '/users',
    name: 'Users',
  },
  {
    path: '/users/:id/edit',
    name: 'Edit Users by Id',
  },
];

const Breadcrumbs = () => {
  const location = useLocation();
  const [crumbs, setCrumbs] = useState([]);

  //   const routes = [{ path: '/members/:id' }];

  const getPaths = () => {
    const allRoutes = matchRoutes(routes, location);
    const matchedRoute = allRoutes ? allRoutes[0] : null;
    let breadcrumbs: IRoute[] = [];
    if (matchedRoute) {
      breadcrumbs = routes
        .filter((x) => matchedRoute.route.path.includes(x.path))
        .map(({ path, ...rest }) => ({
          path: Object.keys(matchedRoute.params).length
            ? Object.keys(matchedRoute.params).reduce(
                (path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string),
                path
              )
            : path,
          ...rest,
        }));
    }
    setCrumbs(breadcrumbs);
  };

  useEffect(() => {
    getPaths();
  }, [location]);

  const goBack = () => {
    window.history.back();
  };

  return (
    
); }; export default Breadcrumbs;

然後我們可以在應用程式的任何部分使用該元件,最好是在佈局中。

結論

我們已經了解瞭如何實現一個簡單的麵包屑組件,我們可以將其添加到我們的應用程式中以改善導航和用戶體驗。

有用的連結

https://stackoverflow.com/questions/66265608/react-router-v6-get-path-pattern-for-current-route

https://medium.com/@mattywilliams/generating-an-automatic-breadcrumb-in-react-router-fed01af1fc3,這篇文章的靈感來自於此。

以上是使用 React Router v6 在 React 中實作麵包屑的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:幫忙解決下一篇:幫忙解決