バイト先でNext.jsを使っていて、v6から入った_app
と、以前からある_document
の違いがよくわかっていなかったので調べてまとめました。基本的にはこれの一部を和訳しているので、よくわからなかったらそちらを参照してください。
_document
これが定義されている場合には、<html>
要素をレンダリングするトップレベルのドキュメントをオーバーライドすることができます。しかし、これにはいくつかの重大な制限が存在します。例えば、Reactは<html>
や<body>
をクライアント側で直接レンダリングすることはできません。そのため、_document
の呼び出しはレンダリング前に限定されます。
_app
_app
はそのほかのユースケースに対しても使うことができます。
Prerender phase | Runtime lifecycle | Data fetching | |
---|---|---|---|
_document |
YES | NO | NO |
_app |
YES | YES | YES |
例1)ページトランジション
この例では、ページごとに独立してアクセスし、プリレンダリングをし、遅延ロードをしていますが、クライアント側に移行するとなめらかなアニメーションを行います。
例2)良質なApolloやReduxとの統合
Nextではすでに、ApolloやReduxのような状態管理フレームワークと統合した例が数多くありましたが、_app
を使えばそれらを含めるのが容易になります。
例3)良質なエラーハンドリング
ReactはcomponentDidCatch
というコンポーネントメソッドを用意しています。このメソッドを使用すると、クライアント側のネストされたコンポーネントの例外をキャッチして処理できます。
これらの予期しない例外は、トップレベルでキャッチして均等に処理しておきたいというケースが多くあります。_app
は、そのcomponentDidCatch
ロジックを定義するのに適しています。
感想
以前までは各ページをHOCに食わせるなどして共通の事前処理を行っていたので、その必要がなくなったということで、HOC地獄から少し開放されたような気がしています。