框架
版本

链接选项

您可能希望重用传递给 Linkredirectnavigate 的选项。在这种情况下,您可能会决定对象字面量是表示传递给 Link 的选项的好方法。

tsx
const dashboardLinkOptions = {
  to: '/dashboard',
  search: { search: '' },
}

function DashboardComponent() {
  return <Link {...dashboardLinkOptions} />
}
const dashboardLinkOptions = {
  to: '/dashboard',
  search: { search: '' },
}

function DashboardComponent() {
  return <Link {...dashboardLinkOptions} />
}

这里有几个问题。dashboardLinkOptions.to 被推断为 string,默认情况下,当传递给 Linknavigateredirect 时,它将解析为每个路由(这个特定问题可以通过 as const 修复)。这里的另一个问题是,我们不知道 dashboardLinkOptions 甚至通过类型检查器,直到它被展开到 Link 中。我们很容易创建不正确的导航选项,只有当选项被展开到 Link 中时,我们才知道有类型错误。

使用 linkOptions 函数创建可重用选项

linkOptions 是一个函数,它对对象字面量进行类型检查并按原样返回推断的输入。这在使用之前为选项提供了与 Link 完全相同的类型安全,允许更容易的维护和重用性。我们上面使用 linkOptions 的示例如下所示:

tsx
const dashboardLinkOptions = linkOptions({
  to: '/dashboard',
  search: { search: '' },
})

function DashboardComponent() {
  return <Link {...dashboardLinkOptions} />
}
const dashboardLinkOptions = linkOptions({
  to: '/dashboard',
  search: { search: '' },
})

function DashboardComponent() {
  return <Link {...dashboardLinkOptions} />
}

这允许对 dashboardLinkOptions 进行急切的类型检查,然后可以在任何地方重用

tsx
const dashboardLinkOptions = linkOptions({
  to: '/dashboard',
  search: { search: '' },
})

export const Route = createFileRoute('/dashboard')({
  component: DashboardComponent,
  validateSearch: (input) => ({ search: input.search }),
  beforeLoad: () => {
    // 可以在 redirect 中使用
    throw redirect(dashboardLinkOptions)
  },
})

function DashboardComponent() {
  const navigate = useNavigate()

  return (
    <div>
      {/** 可以在 navigate 中使用 */}
      <button onClick={() => navigate(dashboardLinkOptions)} />

      {/** 可以在 Link 中使用 */}
      <Link {...dashboardLinkOptions} />
    </div>
  )
}
const dashboardLinkOptions = linkOptions({
  to: '/dashboard',
  search: { search: '' },
})

export const Route = createFileRoute('/dashboard')({
  component: DashboardComponent,
  validateSearch: (input) => ({ search: input.search }),
  beforeLoad: () => {
    // 可以在 redirect 中使用
    throw redirect(dashboardLinkOptions)
  },
})

function DashboardComponent() {
  const navigate = useNavigate()

  return (
    <div>
      {/** 可以在 navigate 中使用 */}
      <button onClick={() => navigate(dashboardLinkOptions)} />

      {/** 可以在 Link 中使用 */}
      <Link {...dashboardLinkOptions} />
    </div>
  )
}

linkOptions 数组

在创建导航时,您可能会循环遍历数组来构建导航栏。在这种情况下,linkOptions 可以用于对用于 Link 属性的对象字面量数组进行类型检查

tsx
const options = linkOptions([
  {
    to: '/dashboard',
    label: 'Summary',
    activeOptions: { exact: true },
  },
  {
    to: '/dashboard/invoices',
    label: 'Invoices',
  },
  {
    to: '/dashboard/users',
    label: 'Users',
  },
])

function DashboardComponent() {
  return (
    <>
      <div className="flex items-center border-b">
        <h2 className="text-xl p-2">Dashboard</h2>
      </div>

      <div className="flex flex-wrap divide-x">
        {options.map((option) => {
          return (
            <Link
              {...option}
              key={option.to}
              activeProps={{ className: `font-bold` }}
              className="p-2"
            >
              {option.label}
            </Link>
          )
        })}
      </div>
      <hr />

      <Outlet />
    </>
  )
}
const options = linkOptions([
  {
    to: '/dashboard',
    label: 'Summary',
    activeOptions: { exact: true },
  },
  {
    to: '/dashboard/invoices',
    label: 'Invoices',
  },
  {
    to: '/dashboard/users',
    label: 'Users',
  },
])

function DashboardComponent() {
  return (
    <>
      <div className="flex items-center border-b">
        <h2 className="text-xl p-2">Dashboard</h2>
      </div>

      <div className="flex flex-wrap divide-x">
        {options.map((option) => {
          return (
            <Link
              {...option}
              key={option.to}
              activeProps={{ className: `font-bold` }}
              className="p-2"
            >
              {option.label}
            </Link>
          )
        })}
      </div>
      <hr />

      <Outlet />
    </>
  )
}

linkOptions 的输入被推断并返回,如使用 label 所示,因为它在 Link 属性上不存在