본문으로 건너뛰기

사용자 지정 Link

많은 상황에서 반복이 허용될 수 있지만, 반복이 너무 잦다고 느낄 수 있습니다. 때로는 동작이나 스타일을 추가한 횡단 관심사 컴포넌트를 만들고 싶을 수 있습니다. TanStack Router의 타입 안전성과 서드 파티 라이브러리를 함께 사용하는 방법도 고려할 수 있습니다.

createLinkLink와 동일한 타입 매개변수를 사용하는 사용자 지정 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를 사용하는 몇 가지 예제입니다.

React

React Aria Components 예제

React Aria Components v1.11.0 이상은 TanStack Router의 preload (intent) prop과 함께 동작합니다. 링크로 사용할 각 React Aria 컴포넌트를 createLink로 감쌉니다.

RACLink.tsx
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)
CustomRACLink.tsx
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 예제

ChakraLinkComponent.tsx
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 예제

이러한 패턴을 사용하는 예제가 있습니다.

MUI Link가 라우터 Link처럼 동작하기만 하면 createLink로 감싸면 됩니다.

CustomLink.tsx
import { createLink } from '@tanstack/react-router'
import { Link } from '@mui/material'

export const CustomLink = createLink(Link)

Link를 사용자 지정하려면 다음 방법을 사용할 수 있습니다.

CustomLink.tsx
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로 사용하려면 componenta로 설정합니다.

CustomButtonLink.tsx
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와 함께 사용할 수 있습니다.

StyledCustomLink.tsx
import { css, styled } from '@mui/material'
import { CustomLink } from './CustomLink'

const StyledCustomLink = styled(CustomLink)(
({ theme }) => css`
color: ${theme.palette.common.white};
`,
)

React

Mantine 예제

CustomLink.tsx
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

일부 라이브러리 예제

UntitledLink.tsx
// TODO: Add this example.