MUIの公式サイトには 様々なフレームワークでの Example が掲載されております。
その中にはもちろん Next.js (TypeScript) でのExample も掲載されています。
基本的にはそのExampleのとおりにやれば、MUIを導入できるのですが…
そのExampleが、色々とツッコミどころがあるのです。
例えば、 any 使いまくるのは TypeScript的にどうなの?
というわけで、Exampleの微妙なところを徹底的に直してみましたので、ぜひ参考にしていただければうれしいです。
ではいきましょう!
前提条件
ライブラリのバージョン
Next.js 12.2.4
MUI 5.10.1
リポジトリはこちら
今回のリポジトリをこちらに公開しておきます。
ぜひ参考にしてみてください。
any を撲滅する
公式Exampleの _document.tsx には、 any が結構使われています。たとえば
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
{/* 略 */}
{(this.props as any).emotionStyleTags}
{/* 略 */}
</Html>
);
}
}
this.props as any
と書いてありますね。
これは props の中に emotionStyleTags が定義されていないから、無理やり any に変換しているわけで、
根本的に解決するなら、 emotionStyleTags を定義すればOKです。こんな感じで↓
+ type MyDocumentProps = {
+ emotionStyleTags: EmotionJSX.Element[]
+ }
+
- export default class MyDocument extends Document {
+ export default class MyDocument extends Document<MyDocumentProps> {
render() {
return (
<Html lang="en">
{/* 略 */}
- {(this.props as any).emotionStyleTags}
+ {this.props.emotionStyleTags}
{/* 略 */}
</Html>
);
}
}
他にも any が使われている箇所があるので、型を調べて、どんどん潰していきます。
詳しくは、修正した後のコードをご覧ください。
let を撲滅する
公式Exampleの createEmotionCache.ts の変数定義に let が使われています。
import createCache from '@emotion/cache';
const isBrowser = typeof document !== 'undefined';
// On the client side, Create a meta tag at the top of the <head> and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
let insertionPoint;
if (isBrowser) {
const emotionInsertionPoint = document.querySelector<HTMLMetaElement>(
'meta[name="emotion-insertion-point"]',
);
insertionPoint = emotionInsertionPoint ?? undefined;
}
return createCache({ key: 'mui-style', insertionPoint });
}
let insertionPoint;
と書いてありますね。
もちろん、 let は完全な悪ではありませんが、使わずにすむのであればそうしたいものです。
(参考: JavaScriptからletを絶滅させ、constのみにするためのレシピ集)
というわけで、 let をなくし、 const を使えるようリファクタリングしてみました↓
import createCache from "@emotion/cache"
import type { EmotionCache } from "@emotion/cache"
// On the client side, Create a meta tag at the top of the <head> and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
const getInsertionPoint = (): HTMLMetaElement | undefined => {
if (typeof document !== "undefined") {
const insertionPoint = document.querySelector<HTMLMetaElement>(
'meta[name="emotion-insertion-point"]'
)
if (insertionPoint != null) {
return insertionPoint
}
}
}
const createEmotionCache = (): EmotionCache => {
return createCache({ key: "mui-style", insertionPoint: getInsertionPoint() })
}
export default createEmotionCache
(ちなみに、 function よりもアロー関数の方が好きなので、ついでに変えています)
修正した後のソースコードはこちらからご覧いただけます。
まとめ
MUI公式のExampleは、もちろんそのまま動きますし、そのまま使うのが悪いとは思いません。
とはいえ、こういう公式サイトに載っているソースコードを、思考停止でそのまま使うのではなく、
なぜそういう書き方をするのか、本当にこの書き方でいいのか
など考えられるようになると、エンジニアとして成長できるのではないかと思います。
というわけで、しっかりと思考を巡らせていきましょう!