主分支
分支
main (6.23.1)dev
版本
6.23.1v4/5.xv3.x
链接
在本页

<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> 的路由匹配的 URL 路径。它可能包含 .. 来链接到层次结构中更上层的路由。在这些情况下,.. 的工作方式与命令行 cd 函数完全相同;每个 .. 都删除父路径的一个段。

当当前 URL 以 / 结尾时,带有 ..<Link to> 的行为与普通 <a href> 不同。<Link to> 会忽略尾部斜杠,并为每个 .. 删除一个 URL 段。但是,当当前 URL 以 / 结尾时,<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" 仅影响相对路径的解析。它不会更改该相对路径解析的“起始”位置。此解析始终相对于路由层次结构中的当前位置(即渲染 Link 的路由)。

如果您希望对当前 URL 而不是路由层次结构使用路径相对路由,您可以使用当前的 locationURL 构造函数(注意尾部斜杠行为)。

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

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

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

preventScrollReset

如果您正在使用 <ScrollRestoration>,这可以让您防止在点击链接时滚动位置重置到窗口顶部。

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

这不会阻止用户使用后退/前进按钮返回到该位置时滚动位置恢复,它只是阻止用户点击链接时重置。

当您可能想要这种行为的一个示例是,一个操作 URL 搜索参数的选项卡列表不在页面顶部。您不希望滚动位置跳到顶部,因为它可能会将切换的内容滚动到视窗之外!

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

replace

如果您希望通过 history.replaceState 替换历史记录堆栈中的当前条目,而不是默认使用 history.pushState,可以使用 replace 属性。

state

state 属性可用于为新位置设置一个状态值,该值存储在 历史记录状态 中。随后可以通过 useLocation() 访问此值。

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

您可以在“新路径”路由上访问此状态值。

let { state } = useLocation();

reloadDocument

reloadDocument 属性可用于跳过客户端路由,并让浏览器正常处理转换(就像它是一个 <a href> 一样)。

unstable_viewTransition

unstable_viewTransition 属性通过将最终状态更新包装在 document.startViewTransition() 中,为此导航启用 视图转换

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

如果您需要为此视图转换应用特定样式,您还需要利用 unstable_useViewTransitionState() 钩子(或查看 NavLink 中的 transitioning 类和 isTransitioning 渲染道具)。

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 被标记为不稳定,可能会在没有重大版本的情况下发生重大更改。