React Portal を使うと、コンポーネント構造の制約を受けずに、アプリケーション内の任意の箇所に DOM を挿入することができます。
モーダルの実装などで役に立つかと思います。
そんな React Portal ですが、Next.js の SSR/SSG を利用したところエラーが出てしまいました。
Portal を利用した処理として document.getElementById
を行っているのですが、サーバーサイドでは document
にアクセスできないためです。
解決策としては、 useState/useEffect
を組み合わせて、クライアント判定することでエラーを回避できました。
import { useEffect, useState } from 'react' import ReactDOM from 'react-dom' export const Foo = () => { const [isClient, setIsClient] = useState(false); useEffect(() => { // クライアント判定 if (typeof window !== undefined) { setIsClient(true) } }, []) useEffect(() => { if (!isClient) { return } // ここでクライアントサイドで行いたい処理など }, [isClient]) if (!isClient) { return null } return ReactDOM.createPortal( // 挿入したいコンポーネント <SomeComponent>, // 挿入先 document.getElementById('portal-target') ) };