🧁

Chakra UIの<Link>はNextの<Link>じゃない!

1 min read

1. 今さら気づいたこと

ページ遷移のときに、プログレスバーを表示させようと NextNprogress を導入しました。
Chakra UIを使い始めてから何か違和感があるな...と思っていたら、ページ遷移ごとに全てのコンテンツがリロードされているではないか...😖😖😖

何も考えずに使っていたChakra UIのLinkは実はNextのRouter Linkではないため、<a>タグのようにページ全体をリロードしてしまいます。

今回はChakra UIの<LinkをNextの<Link>に置き換えて、快適に使えるようにする方法を考えてみます。

2. as propsがあるじゃん

Chakra UIにはas propsという、コンポーネントの振る舞いを変更できる機能があります。例えば、<Box as="button">のようにするとBoxコンポーネントをButtonコンポーネントのように振る舞わせることができます。

このpropsを使えば、Chakra UIの<Link>をNextの<Link>に簡単に置き換えることができます。

import React from 'react';
import NextLink from 'next/link';
import { Link, LinkProps } from '@chakra-ui/react';

const ModifiedLink: React.FC<LinkProps> = (props) => {
  return (
    <Link as={NextLink} {...props} />
  );
};

export default ModifiedLink;

ところがこの方法ではChakra UIのスタイルが適用されません。Linkにスタイルをつけないと、Chakra UIを使っている意味の20%くらいが減少してしまいます...

3. ではどうするか

Chakra UIのスタイルを保ちつつ、NextLinkを使わせるには外側から囲むのが手っ取り早いと思います。
アクセシビリティのためにLinkにfocusをつけていると思いますが、NextLinkをクリックした後もフォーカス状態になってしまうため、クリック後に解除する処理をつけてあげます。

components/Link/index.tsx
import React from 'react';
import NextLink from 'next/link';
import { Link, LinkProps } from '@chakra-ui/react';

const ModifiedLink: React.FC<LinkProps> = (props) => {
  return (
    <NextLink href={props.href}>
      <Link {...props} onClick={() => (document.activeElement as HTMLElement).blur()} />
    </NextLink>
  );
};

export default ModifiedLink;

あとは通常通りimportして使えばOKです。カスタムした変数部分も無事に動作しています。

sample.tsx
import Link from 'components/Link';

const Logo: React.FC = () => {
  return (
    <Link href="/" mx={6}>
      <Box></Box>
    </Link>
  );
};

4. まとめ

Chakra UIの<Link>がNextLinkではないのは、ちょっとした落とし穴でした。
今回は以上となります。次回もお楽しみに〜〜✨

いつもご支援ありがとうございます!

Discussion

ログインするとコメントできます