main
分支
main (6.23.1)dev
版本
6.23.1v4/5.xv3.x
Link
本頁內容

<Link>

這是 <Link> 的網頁版本。如要取得 `React Native` 版本,請按這裡

類型宣告
declare function Link(props: LinkProps): React.ReactElement;

interface LinkProps
  extends Omit<
    React.AnchorHTMLAttributes<HTMLAnchorElement>,
    "href"
  > {
  to: To;
  preventScrollReset?: boolean;
  relative?: "route" | "path";
  reloadDocument?: boolean;
  replace?: boolean;
  state?: any;
  unstable_viewTransition?: boolean;
}

type To = string | Partial<Path>;

interface Path {
  pathname: string;
  search: string;
  hash: string;
}

<Link> 是一種讓使用者可以透過點擊或點選來導覽到其他頁面的元素。在 react-router-dom 中,<Link> 會產生一個可及的 <a> 元素,其中包含真正連結到它所連結的資源的 href。這代表著例如對 <Link> 按下滑鼠右鍵等類似行為會如你所預期般運作。你可以使用 <Link reloadDocument> 來略過客戶端路由,並讓瀏覽器正常處理轉換(就像一個 <a href>)。

import * as React from "react";
import { Link } from "react-router-dom";

function UsersIndexPage({ users }) {
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            <Link to={user.id}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

相對的 <Link to> 值(不以 / 開頭)會相對於父路徑進行解析,這代表它會建構在產生該 <Link> 路徑的路由所比對到的網址路徑上。它可以包含 .. 來連結到階層中較上層的路徑。在這些狀況下,.. 會完全像指令列中的 cd 功能一樣運作;每個 .. 會移除一個父層路徑區段。

當目前的網址以 / 作結尾時,包含 ..<Link to> 和一般的 <a href> 會有不同的行為。<Link to> 會忽略尾部斜線,並根據每一個 .. 刪除一個網址區段。但是 <a href> 的值會在目前的網址以 / 作結尾或不作結尾時,以不同的方式處理 ..

請參閱 useResolvedPath 文件中的 Splat 路徑 區段,以取得關於 future.v7_relativeSplatPath 未來旗標行為的說明,該旗標適用於 splat 路徑中的相對 <Link to> 行為

relative

預設情況下,連結會與路由層級相關聯(relative="route"),因此 .. 會從目前的脈絡路由向上移動一個 Route 層級。偶爾您可能會發現您有嵌套在一起沒有意義的 URL 模式,而您希望從目前的脈絡路由路徑使用相對 路徑 路由。您可以使用 relative="path" 選擇這個行為

// Contact and EditContact do not share additional UI layout
<Route path="/" element={<Layout />}>
  <Route path="contacts/:id" element={<Contact />} />
  <Route
    path="contacts/:id/edit"
    element={<EditContact />}
  />
</Route>;

function EditContact() {
  // Since Contact is not a parent of EditContact we need to go up one level
  // in the current contextual route path, instead of one level in the Route
  // hierarchy
  return (
    <Link to=".." relative="path">
      Cancel
    </Link>
  );
}

請注意,relative: "path" 僅會影響相對路徑的解析。它不會變更相對路徑解析的「起始」位置。此解析總是會與 Route 層級中的目前位置相關(亦即,顯示 Link 的路由)

如果您希望相對於目前的網址,而非路由層級使用路徑相對路由,您可以使用目前的 locationURL 結構(請注意尾部斜線的行為)

// Assume the current URL is https://remix.dev.org.tw/docs/en/main/start/quickstart
let location = useLocation();

// Without trailing slashes
new URL(".", window.origin + location.pathname);
// 'https://remix.dev.org.tw/docs/en/main/start/'
new URL("..", window.origin + location.pathname);
// 'https://remix.dev.org.tw/docs/en/main/'

// With trailing slashes:
new URL(".", window.origin + location.pathname + "/");
// 'https://remix.dev.org.tw/docs/en/main/start/quickstart/'
new URL("..", window.origin + location.pathname + "/");
// 'https://remix.dev.org.tw/docs/en/main/start/'

preventScrollReset

如果您正在使用 <ScrollRestoration>,這讓您可以避免當點擊連結時,捲動位置重設回視窗的最上方。

<Link to="?tab=one" preventScrollReset={true} />

它無法避免當使用者以返回/前進按鈕回到位置時,捲動位置重設,它僅能避免在使用者點擊連結時重設。

您可能會想要有這種行為的一個範例,是列出一些標籤,它們會操控位於網頁最上方的網址搜尋參數。您不會希望捲動位置跳回到最上方,因為它可能會將折疊的內容捲動到視窗外!

      ┌─────────────────────────┐
      │                         ├──┐
      │                         │  │
      │                         │  │ scrolled
      │                         │  │ out of view
      │                         │  │
      │                         │ ◄┘
    ┌─┴─────────────────────────┴─┐
    │                             ├─┐
    │                             │ │ viewport
    │   ┌─────────────────────┐   │ │
    │   │  tab   tab   tab    │   │ │
    │   ├─────────────────────┤   │ │
    │   │                     │   │ │
    │   │                     │   │ │
    │   │ content             │   │ │
    │   │                     │   │ │
    │   │                     │   │ │
    │   └─────────────────────┘   │ │
    │                             │◄┘
    └─────────────────────────────┘

replace

replace 屬性可以用在您想要透過 history.replaceState 取代歷史記錄堆疊中的目前輸入,而非預設使用 history.pushState

state

使用 state 屬性可以為儲存在 歷史狀態 中的新位置設定一種有狀態值。隨後,可用 useLocation() 存取此值。

<Link to="new-path" state={{ some: "value" }} />

您可以在「new-path」路徑上存取此狀態值

let { state } = useLocation();

reloadDocument

reloadDocument 屬性用於略過用戶端路由,並讓瀏覽器正常處理轉換(就像 <a href> 一樣)。

unstable_viewTransition

unstable_viewTransition prop 會針對此導航啟用 檢視轉換,方法是在 document.startViewTransition() 中包裝最終狀態更新

<Link to={to} unstable_viewTransition>
  Click me
</Link>

如果需要針對此檢視轉換套用特定樣式,您也需要活用 unstable_useViewTransitionState() 勾子(或查看 NavLink 中的 transitioning 類別和 isTransitioning 呈現 prop)

function ImageLink(to) {
  const isTransitioning =
    unstable_useViewTransitionState(to);
  return (
    <Link to={to} unstable_viewTransition>
      <p
        style={{
          viewTransitionName: isTransitioning
            ? "image-title"
            : "",
        }}
      >
        Image Number {idx}
      </p>
      <img
        src={src}
        alt={`Img ${idx}`}
        style={{
          viewTransitionName: isTransitioning
            ? "image-expand"
            : "",
        }}
      />
    </Link>
  );
}

unstable_viewTransition 僅在使用資料路由時有效,請參閱 挑選路由

請注意,此 API 標示為不穩定,在未進行重大更新的情況下可能會有所變更