🐙

DarkMode切替時でのHydration errorの対応策

2024/09/12に公開

問題

shadcn/uiにてDarkModeの切替をnext-themesを使って実装した場合に
Hydration errorが出てしまう問題についての対応策になります。

https://github.com/shadcn-ui/ui/issues/1906
上記でissueとして上がっているものと同様の現象です。
(解決してないけどcloseされてるのはご愛嬌w)

とりあえずエラー消したい場合

supressHydrationWarningをtrueにするとエラーは消えます。

<html lang="ja" suppressHydrationWarning>
  <body className={inter.className}>
    {children}
  </body>
</html>

エラーは消えますがコンソールに表示されなくなっているだけなので根本解決ではないので
少し気にはなります。。。

結論

'use client';

import { ThemeProvider as NextThemeProvider } from 'next-themes';
import { type ThemeProviderProps } from 'next-themes/dist/types';
import { useEffect, useState } from 'react';

export const ThemeProvider = ({ children, ...props }: ThemeProviderProps) => {
  const [mounted, setMounted] = useState<boolean>(false);
  useEffect(() => {
    setMounted(true);
    return () => setMounted(false);
  }, []);
  return (
    mounted && <NextThemeProvider {...props}>{children}</NextThemeProvider>
  );
};

useEffectでmountedのタイミングを待ってproviderを活性にするとミスマッチ分(clientとの差分)がmountedが終わったのを待ってRenderingされるのでエラーは解消されます。

感想

issue解決してないのにcloseにすんなよw っていう思い

Discussion