사용자 지정 Link
많은 상황에서 반복이 허용될 수 있지만, 반복이 너무 잦다고 느낄 수 있습니다. 때로는 동작이나 스타일을 추가한 횡단 관심사 컴포넌트를 만들고 싶을 수 있습니다. TanStack Router의 타입 안전성과 서드 파티 라이브러리를 함께 사용하는 방법도 고려할 수 있습니다.
횡단 관심사를 위한 createLink
createLink는 Link와 동일한 타입 매개변수를 사용하는 사용자 지정 Link 컴포넌트를 만듭니다. 따라서 Link와 동일한 타입 안전성과 TypeScript 성능을 제공하는 자체 컴포넌트를 만들 수 있습니다.
기본 예제
기본 사용자 지정 링크 컴포넌트를 만들려면 다음과 같이 작성합니다.
React
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} />
}
Solid
import * as Solid from 'solid-js'
import { createLink, LinkComponent } from '@tanstack/solid-router'
export const Route = createRootRoute({
component: RootComponent,
})
type BasicLinkProps = Solid.JSX.IntrinsicElements['a'] & {
// Add any additional props you want to pass to the anchor element
}
const BasicLinkComponent: Solid.Component<BasicLinkProps> = (props) => (
<a {...props} class="block px-3 py-2 text-red-700">
{props.children}
</a>
)
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 }} />
서드 파티 라이브러리와 함께 사용하는 createLink
다음은 서드 파티 라이브러리와 함께 createLink를 사용하는 몇 가지 예제입니다.
React
React Aria Components 예제
React Aria Components v1.11.0 이상은 TanStack Router의 preload (intent) prop과 함께 동작합니다. 링크로 사용할 각 React Aria 컴포넌트를 createLink로 감쌉니다.
import { createLink } from '@tanstack/react-router'
import { Link as RACLink, MenuItem } from 'react-aria-components'
export const Link = createLink(RACLink)
export const MenuItemLink = createLink(MenuItem)
import { createLink } from '@tanstack/react-router'
import { Link as RACLink, type LinkProps } from 'react-aria-components'
interface MyLinkProps extends LinkProps {
// your props
}
function MyLink(props: MyLinkProps) {
return (
<RACLink
{...props}
style={({ isHovered }) => ({
color: isHovered ? 'red' : 'blue',
})}
/>
)
}
export const Link = createLink(MyLink)
className, style, children 함수를 포함한 React Aria의 렌더 prop을 사용하려면 래퍼 컴포넌트를 만들고 이를 createLink에 전달합니다.
React
Chakra UI 예제
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}
/>
)
}
React
MUI 예제
이러한 패턴을 사용하는 예제가 있습니다.
Link
MUI Link가 라우터 Link처럼 동작하기만 하면 createLink로 감싸면 됩니다.
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
Button
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} />
}
styled와 함께 사용
이러한 MUI 방법은 모두 styled와 함께 사용할 수 있습니다.
import { css, styled } from '@mui/material'
import { CustomLink } from './CustomLink'
const StyledCustomLink = styled(CustomLink)(
({ theme }) => css`
color: ${theme.palette.common.white};
`,
)
React
Mantine 예제
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} />
}
Solid
일부 라이브러리 예제
// TODO: Add this example.