🦆

【Next.js + Chakra UI】どちらのLinkを使えばいいの?

2022/01/19に公開
3

はじめに

Next.js + ChakraUI でアプリを実装している時に、「どちらのLinkを使えばいいの?」と疑問に思ったので調べつつ実装について考えてみました。

それぞれのLinkについて

https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/next/link

Client-side transitions between routes can be enabled via the Link component exported by next/link.

Next.jsにはページの概念に基づいたファイルシステムのルーターがデフォルトで存在するので、NextLinkを利用することでクライアント側での遷移が可能

https://chakra-ui.com/docs/navigation/link

Links are accessible elements used primarily for navigation. This component is styled to resemble a hyperlink and semantically renders an <a>.

一方、ChakraUILinkではaタグに似た挙動となる

比較

それぞれのLinkを単体で用いた場合の挙動を比較してみます。

ブラウザの検証ツールで背景に色をつけて比較してみるとChakraUIのLinkのみを用いた場合、画面が一度リロードされるのに対し、Next.jsのLinkを用いた場合は画面をロードすることなく遷移することができました。

結局どちらのLinkを使うのがいいの?

挙動をみてもわかるようにNextLinkを使うのが好ましいです。しかし、ChakraUIのスタイルの恩恵を受けたいというのも本音です。

ChakraUIのスタイルを使いつつNextLinkで遷移できるような実装がベストなのではと考えられそうです。

実装

NextLinkでChakraUIを囲うことで、画面遷移の責務はNextLinkで担いスタイルはChakraUIを用いることができました。また、passHrefasでaタグを付与することでSEO的にも問題なく実装することができます。

作成したコンポーネント

components/sample-link.tsx
import React from 'react';
import NextLink from 'next/link'

type SampleLinkProps = {
  children: React.ReactNode
  href: string
}

export const SampleLink = ({children, href}: SampleLinkProps) => {
  return (
    <NextLink href={href} passHref>
      {children}
    </NextLink>
  )
}

ChakraUIのLinkを使用した場合

import { SampleLink } from '@components'
import { Link as ChakraUILink } from '@chakra-ui/react'

<SampleLink href={'/sample'}>
  <ChakraUILink>to SamplePage</ChakraUILink>
</SampleLink>

ChakraUIのLink以外の要素を使用した場合

import { SampleLink } from '@components'
import { Link as ChakraUIButton } from '@chakra-ui/react'
	
<SampleLink href={'/sample'}>
  <ChakraUIButton as={'a'}>to SamplePage</ChakraUIButton>
</SampleLink>

追記

NextLinkをコンポーポーネン化すると若干わかりづらくなってしまうため、コンポーネント化しないパータンを追記

ChakraUIのLinkを使用した場合(ChakraUIドキュメント

import NextLink from 'next/link'
import { Link as ChakraUILink } from '@chakra-ui/react'

<NextLink href={'/sample'} passHref>
  <ChakraUILink>to SamplePage</ChakraUILink>
</NextLink>

ChakraUIのLink以外の要素を使用した場合

import NextLink from 'next/link'
import { Button as ChakraUIButton } from '@chakra-ui/react'
	
<NextLink href={'/sample'}>
  <ChakraUIButton as={'a'}>to SamplePage</ChakraUIButton>
</NextLink>

試して微妙だった方法

as props を使用してChakraUILinkにNextLinkの挙動をさせる

NextLinkの要素を割り当ててChakraUIのスタイルを保持しつつNextLinkの挙動を期待していたのですが、下記の実装ではスタイルをうまく当てることができなくなってしまいました。

import NextLink from 'next/link'
import { Link as ChakraUILink, LinkProps as ChakraUILinkProps } from '@chakra-ui/react'

export const SampleLink = (props: ChakraUILinkProps) => {
  return (
    <ChakraUILink as={NextLink} {...props} />
  )
}

まとめ

UIコンポーネントを使ってると「あれ、これどうしたらいいの?」という場面に遭遇することも多々。いろんな方法を模索するのも楽しいものです!

Discussion