当サイトは、アフィリエイト広告を利用しています

【React × Gatsby】デバイスのダークモードを判定する

作成日:2023月02月04日
更新日:2024年01月28日

当ブログではユーザのデバイスのモードがダークモードに設定されている場合は
ブログを開いた時にブログもそれに合わせてダークモードになるよう実装した。 その際、Reactでユーザーのデバイスのモード判定をどう行ったかをメモしておく

Reactでデバイスのダークモードを判定する方法

ユーザーのデバイスがダークモードかどうかを判定するためには
下記を使って実装する。

  • useState
  • window.matchMedia()

window.matchMedia()とは?

CSSのメディアクエリをJavaScriptで使用する時に使うメソッド。 簡単にReactでサンプルを書いてみる。

App.jsx
import React, { useState } from "react";
export default function App() {
const [width, setWidth] = useState(() => {
return window.matchMedia("(min-width: 500px)").matches ? true : false;
});
return (
<div className="App">
{width && <h1>widthが500px以上です</h1>}
{width || <h1>widthが500px未満です</h1>}
</div>
);
}

画面の大きさを変えてリロードすれば表示される文字が
画面のwidthによって変更される。
codesandboxの実装例を載せます。

React_js_mediaquery

javascriptでメディアクエリ使っているため、画面の大きさを変えても
リロードしないと表示文字は変更されない。

画面の大きさを変えると同時に変更したい場合は
下記にEmotionを使った方法載せときます。

window.matchMedia()でダークモードを判定する

window.matchMedia()を使ってダークモードを判定してみる

App.jsx
import React, { useState } from "react";
export default function App() {
const [colorMode, setColorMode] = useState(() => {
return window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
});
return (
<div className="App">
{colorMode === "dark" && <h1>デバイスはダークモードです</h1>}
{colorMode === "light" && <h1>デバイスはライトモードです</h1>}
</div>
);
}
  • matchMediaメソッドでprefers-color-scheme: darkを使って判定する。

React_device_mode_judge

参考

Gatsbyでデバイスのダークモードを判定する方法

ReactのフレームワークのGatsbyでダークモードを判定する場合は
基本的には同じ書き方でできるが、少し追加する必要がある。

window is not definedが発生する

上記と同様のコードをGatsbyで書いて動かした場合、「gatsby develop」では正常に動作するが
「gatsby build」を実行したときはwindow is not definedのエラーが発生する。

そのため少し手を加えてやる必要がある。

App.jsx
import React, { useState } from "react";
export default function App() {
const [colorMode, setColorMode] = useState(() => {
if (typeof window !== "undefined" && typeof document !== "undefined") {
return window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
}
});
return (
<div className="App">
{colorMode === "dark" && <h1>デバイスはダークモードです</h1>}
{colorMode === "light" && <h1>デバイスはライトモードです</h1>}
</div>
);
}

Gatsbyでbuild時にはwindowやdocumentなどのブラウザのグローバルオブジェクトを
参照している場合はエラーになるので、undefinedかチェックをしてやる必要がある。

まとめ

emotionでメディアクエリを使えることを知っていたが
javascrptでも使えることは知らなかった。
なんだかんだでほとんどのことはjavascriptはできる気がする

新着記事

タグ別一覧
top