虽然在许多情况下重复自己是可以接受的,但您可能会发现您做得过于频繁。有时,您可能希望创建具有附加行为或样式的横切组件。您也可以考虑将第三方库与 TanStack Router 的类型安全结合使用。
createLink 创建一个自定义的 Link 组件,该组件具有与 Link 相同的类型参数。这意味着您可以创建自己的组件,该组件提供与 Link 相同的类型安全性和 typescript 性能。
如果您想创建一个基本的自定义链接组件,可以使用以下方法进行创建
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
interface BasicLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
// Add any additional props you want to pass to the anchor element
}
const BasicLinkComponent = React.forwardRef<HTMLAnchorElement, BasicLinkProps>(
(props, ref) => {
return (
<a ref={ref} {...props} className={'block px-3 py-2 text-blue-700'} />
)
},
)
const CreatedLinkComponent = createLink(BasicLinkComponent)
export const CustomLink: LinkComponent<typeof BasicLinkComponent> = (props) => {
return <CreatedLinkComponent preload={'intent'} {...props} />
}
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
interface BasicLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
// Add any additional props you want to pass to the anchor element
}
const BasicLinkComponent = React.forwardRef<HTMLAnchorElement, BasicLinkProps>(
(props, ref) => {
return (
<a ref={ref} {...props} className={'block px-3 py-2 text-blue-700'} />
)
},
)
const CreatedLinkComponent = createLink(BasicLinkComponent)
export const CustomLink: LinkComponent<typeof BasicLinkComponent> = (props) => {
return <CreatedLinkComponent preload={'intent'} {...props} />
}
然后,您可以像使用任何其他 Link 一样使用您新创建的 Link 组件
<CustomLink to={'/dashboard/invoices/$invoiceId'} params={{ invoiceId: 0 }} />
<CustomLink to={'/dashboard/invoices/$invoiceId'} params={{ invoiceId: 0 }} />
以下是一些关于如何将 createLink 与第三方库一起使用的示例。
React Aria Components 的 Link 组件不支持标准的 onMouseEnter 和 onMouseLeave 事件。因此,您不能将其直接与 TanStack Router 的 preload (intent) 属性一起使用。
对此的解释可以在这里找到
可以通过将 useLink hook 与来自 React Aria Hooks 的标准锚元素一起使用来解决此问题。
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
import {
mergeProps,
useFocusRing,
useHover,
useLink,
useObjectRef,
} from 'react-aria'
import type { AriaLinkOptions } from 'react-aria'
interface RACLinkProps extends Omit<AriaLinkOptions, 'href'> {
children?: React.ReactNode
}
const RACLinkComponent = React.forwardRef<HTMLAnchorElement, RACLinkProps>(
(props, forwardedRef) => {
const ref = useObjectRef(forwardedRef)
const { isPressed, linkProps } = useLink(props, ref)
const { isHovered, hoverProps } = useHover(props)
const { isFocusVisible, isFocused, focusProps } = useFocusRing(props)
return (
<a
{...mergeProps(linkProps, hoverProps, focusProps, props)}
ref={ref}
data-hovered={isHovered || undefined}
data-pressed={isPressed || undefined}
data-focus-visible={isFocusVisible || undefined}
data-focused={isFocused || undefined}
/>
)
},
)
const CreatedLinkComponent = createLink(RACLinkComponent)
export const CustomLink: LinkComponent<typeof RACLinkComponent> = (props) => {
return <CreatedLinkComponent preload={'intent'} {...props} />
}
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
import {
mergeProps,
useFocusRing,
useHover,
useLink,
useObjectRef,
} from 'react-aria'
import type { AriaLinkOptions } from 'react-aria'
interface RACLinkProps extends Omit<AriaLinkOptions, 'href'> {
children?: React.ReactNode
}
const RACLinkComponent = React.forwardRef<HTMLAnchorElement, RACLinkProps>(
(props, forwardedRef) => {
const ref = useObjectRef(forwardedRef)
const { isPressed, linkProps } = useLink(props, ref)
const { isHovered, hoverProps } = useHover(props)
const { isFocusVisible, isFocused, focusProps } = useFocusRing(props)
return (
<a
{...mergeProps(linkProps, hoverProps, focusProps, props)}
ref={ref}
data-hovered={isHovered || undefined}
data-pressed={isPressed || undefined}
data-focus-visible={isFocusVisible || undefined}
data-focused={isFocused || undefined}
/>
)
},
)
const CreatedLinkComponent = createLink(RACLinkComponent)
export const CustomLink: LinkComponent<typeof RACLinkComponent> = (props) => {
return <CreatedLinkComponent preload={'intent'} {...props} />
}
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
import { Link } from '@chakra-ui/react'
interface ChakraLinkProps
extends Omit<React.ComponentPropsWithoutRef<typeof Link>, 'href'> {
// Add any additional props you want to pass to the link
}
const ChakraLinkComponent = React.forwardRef<
HTMLAnchorElement,
ChakraLinkProps
>((props, ref) => {
return <Link ref={ref} {...props} />
})
const CreatedLinkComponent = createLink(ChakraLinkComponent)
export const CustomLink: LinkComponent<typeof ChakraLinkComponent> = (
props,
) => {
return (
<CreatedLinkComponent
textDecoration={'underline'}
_hover={{ textDecoration: 'none' }}
_focus={{ textDecoration: 'none' }}
preload={'intent'}
{...props}
/>
)
}
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
import { Link } from '@chakra-ui/react'
interface ChakraLinkProps
extends Omit<React.ComponentPropsWithoutRef<typeof Link>, 'href'> {
// Add any additional props you want to pass to the link
}
const ChakraLinkComponent = React.forwardRef<
HTMLAnchorElement,
ChakraLinkProps
>((props, ref) => {
return <Link ref={ref} {...props} />
})
const CreatedLinkComponent = createLink(ChakraLinkComponent)
export const CustomLink: LinkComponent<typeof ChakraLinkComponent> = (
props,
) => {
return (
<CreatedLinkComponent
textDecoration={'underline'}
_hover={{ textDecoration: 'none' }}
_focus={{ textDecoration: 'none' }}
preload={'intent'}
{...props}
/>
)
}
有一个使用这些模式的示例可用。
如果 MUI 的 Link 应该像路由器 Link 一样简单地运行,则只需用 createLink 包裹即可
import { createLink } from '@tanstack/react-router'
import { Link } from '@mui/material'
export const CustomLink = createLink(Link)
import { createLink } from '@tanstack/react-router'
import { Link } from '@mui/material'
export const CustomLink = createLink(Link)
如果 Link 应该被自定义,则可以使用此方法
import React from 'react'
import { createLink } from '@tanstack/react-router'
import { Link } from '@mui/material'
import type { LinkProps } from '@mui/material'
import type { LinkComponent } from '@tanstack/react-router'
interface MUILinkProps extends LinkProps {
// Add any additional props you want to pass to the Link
}
const MUILinkComponent = React.forwardRef<HTMLAnchorElement, MUILinkProps>(
(props, ref) => <Link ref={ref} {...props} />,
)
const CreatedLinkComponent = createLink(MUILinkComponent)
export const CustomLink: LinkComponent<typeof MUILinkComponent> = (props) => {
return <CreatedLinkComponent preload={'intent'} {...props} />
}
// Can also be styled
import React from 'react'
import { createLink } from '@tanstack/react-router'
import { Link } from '@mui/material'
import type { LinkProps } from '@mui/material'
import type { LinkComponent } from '@tanstack/react-router'
interface MUILinkProps extends LinkProps {
// Add any additional props you want to pass to the Link
}
const MUILinkComponent = React.forwardRef<HTMLAnchorElement, MUILinkProps>(
(props, ref) => <Link ref={ref} {...props} />,
)
const CreatedLinkComponent = createLink(MUILinkComponent)
export const CustomLink: LinkComponent<typeof MUILinkComponent> = (props) => {
return <CreatedLinkComponent preload={'intent'} {...props} />
}
// Can also be styled
如果 Button 应该用作路由器 Link,则应将 component 设置为 a
import React from 'react'
import { createLink } from '@tanstack/react-router'
import { Button } from '@mui/material'
import type { ButtonProps } from '@mui/material'
import type { LinkComponent } from '@tanstack/react-router'
interface MUIButtonLinkProps extends ButtonProps<'a'> {
// Add any additional props you want to pass to the Button
}
const MUIButtonLinkComponent = React.forwardRef<
HTMLAnchorElement,
MUIButtonLinkProps
>((props, ref) => <Button ref={ref} component="a" {...props} />)
const CreatedButtonLinkComponent = createLink(MUIButtonLinkComponent)
export const CustomButtonLink: LinkComponent<typeof MUIButtonLinkComponent> = (
props,
) => {
return <CreatedButtonLinkComponent preload={'intent'} {...props} />
}
import React from 'react'
import { createLink } from '@tanstack/react-router'
import { Button } from '@mui/material'
import type { ButtonProps } from '@mui/material'
import type { LinkComponent } from '@tanstack/react-router'
interface MUIButtonLinkProps extends ButtonProps<'a'> {
// Add any additional props you want to pass to the Button
}
const MUIButtonLinkComponent = React.forwardRef<
HTMLAnchorElement,
MUIButtonLinkProps
>((props, ref) => <Button ref={ref} component="a" {...props} />)
const CreatedButtonLinkComponent = createLink(MUIButtonLinkComponent)
export const CustomButtonLink: LinkComponent<typeof MUIButtonLinkComponent> = (
props,
) => {
return <CreatedButtonLinkComponent preload={'intent'} {...props} />
}
然后,任何这些 MUI 方法都可以与 styled 一起使用
import { css, styled } from '@mui/material'
import { CustomLink } from './CustomLink'
const StyledCustomLink = styled(CustomLink)(
({ theme }) => css`
color: ${theme.palette.common.white};
`,
)
import { css, styled } from '@mui/material'
import { CustomLink } from './CustomLink'
const StyledCustomLink = styled(CustomLink)(
({ theme }) => css`
color: ${theme.palette.common.white};
`,
)
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
import { Anchor, AnchorProps } from '@mantine/core'
interface MantineAnchorProps extends Omit<AnchorProps, 'href'> {
// Add any additional props you want to pass to the anchor
}
const MantineLinkComponent = React.forwardRef<
HTMLAnchorElement,
MantineAnchorProps
>((props, ref) => {
return <Anchor ref={ref} {...props} />
})
const CreatedLinkComponent = createLink(MantineLinkComponent)
export const CustomLink: LinkComponent<typeof MantineLinkComponent> = (
props,
) => {
return <CreatedLinkComponent preload="intent" {...props} />
}
import * as React from 'react'
import { createLink, LinkComponent } from '@tanstack/react-router'
import { Anchor, AnchorProps } from '@mantine/core'
interface MantineAnchorProps extends Omit<AnchorProps, 'href'> {
// Add any additional props you want to pass to the anchor
}
const MantineLinkComponent = React.forwardRef<
HTMLAnchorElement,
MantineAnchorProps
>((props, ref) => {
return <Anchor ref={ref} {...props} />
})
const CreatedLinkComponent = createLink(MantineLinkComponent)
export const CustomLink: LinkComponent<typeof MantineLinkComponent> = (
props,
) => {
return <CreatedLinkComponent preload="intent" {...props} />
}
您的每周 JavaScript 新闻速递。每周一免费发送给超过 100,000 名开发者。