見出し画像

Material-UIでNext.jsのポイントを紹介する

reactで使う場合とnext.jsで使う場合でmaterial-uiの使い方が微妙に変わってくるので紹介します。

1. SSRへの対応

material-uiはデフォルトではSSRに対応していません。以下のような警告が出ると思います。

Warning: Prop 'className' did not match. Server ...

この警告が出るとcssが反映されずページが崩れると思います。名前通りサーバーで生成したクラス名、クライアントで生成したクラス名が合わなかったと言う状態です。

直し方

こちらのmaterial-ui公式リポジトリ(https://github.com/mui-org/material-ui/tree/master/examples/nextjs)に例を載せてくれています。このリポジトリの_app.jsのuseEffect部,_document.js(そのまま)をコピペすれば解決します。tsxでも同じです。

2.linkの対策

material-ui、nextjs両方でLinkと言うコンポーネントが存在します。名前の通りリンクを設定するようなコンポーネントです。それぞれのドキュメント 

next.js : https://nextjs.org/docs/api-reference/next/link

material-ui : https://material-ui.com/components/links/#links

デザインはしっかり見せたいがnextjsのリンクを使わないとプリフェッチしてくれないのでページ表示までの時間が長くなってしまいます。

解決法

1. next.jsのlinkの中にボタンを入れる

import Link from 'next/link';
import { Button } from '@material-ui/core';  
  
<Link href='/test2' passHref>
    <Button>LinkButton</Button>
</Link>

やり方としては単純だと思います。このようにすればlinkはしっかりと仕事をしてくれます。

2.名前を変えてインポートし同時に使う

import Link from 'next/link';
import { Link as MLink, Button } from '@material-ui/core';

<MLink>
    <Link href='/test2'>test2</Link>
</MLink>

結構無理矢理ですがこのように実装することにより同時に使うことができるようになります。

デザイン比較

おい、その場合の見た目はどうなんだよ!と聞かれそうなのでそのデザインも載せておきます。

スクリーンショット 2021-05-11 21.59.08

ソースコードは以下で出力させています。

import React from 'react';
import Link from 'next/link';
import { Link as MLink, Button } from '@material-ui/core';

const links = () => {
 return (
   <>
     <Link href='#' passHref>
       <Button>解決法1</Button>
     </Link>

     <MLink>
       <Link href='#'>解決法2</Link>
     </MLink>

     <MLink href='#'>
       <Button>リンク+ボタン両方material-ui</Button>
     </MLink>

     <MLink>リンクのみ</MLink>

     <a>aリンクのみ</a>
   </>
 );
};

export default links;

まとめ

SSRへの対応は忘れた頃にエラーに悩まされる気がします。

リンクに関してですが解決法はどちらでも良いです。またその他にも解決法があると思うので実際に画面を見て見た目を比較しながら気に入ったものを使ってください!ただmaterial uiのみで解決させようとしたりするとプリフェッチしてくれずページ遷移に時間がかかってしまうので気をつけてください。

この記事が気に入ったらサポートをしてみませんか?