2021-9-12

[Next.js] サーバーから吐かれるコードを意識する

雑な技術メモ

結論

windowオブジェクトなどサーバーで使えないものを使うときはuseEffect等を利用してクライアントだけで実行されるようにする必要がある。

詳細

  • サーバーとクライアント両方で実行されるコードは、挙動を一致させないといけない

    • Next.jsはSSGにしろSSRにしろ、サーバーで生成されたHTMLがクライアントでまず動作する
  • windowオブジェクトなど、サーバーで使えないものを何も考えずに使用すると、サーバーとクライアントで実行結果が異なり異常な挙動をしてしまう

    • export const SampleComponent = () => {
        // 次の行はクライアントとサーバー双方で実行されるが、実行結果が異なってしまう
        const isMobile = uaIsMobile(window.navigator.userAgent)
      
        ~
      }
      
  • なので、windowオブジェクトなどを使う際は、 useEffect 内で実行する等、クライアントのみで実行されるようにする必要がある。

    • export const SampleComponent = () => {
        // useEffect内はサーバーで実行されないため、問題が発生しない
        const [isMobile, setIsMobile] = useState(false)
        useEffect(() => {
          setIsMobile(uaIsMobile(window.navigator.userAgent))
        }, [])
      
        ~
      }
      
  • この事を踏まえると、Next.jsでも使用できるコンポーネントを作る際は、レンダリングタイミングで実行される処理にブラウザ特有のものが無いか注意する必要があるなと思った。