Nextの進化がすごい今日この頃です。
キャッチアップしている中で学びがあったので、せっかくなので?記事にすることにしました。
遭遇した事象
例えば、Note一覧を表示するような際に以下のような実装をしていました。
app/notes/page.tsxexport default async function Page() { const notes = await getNotes(); return ( <div> {/* Note一覧を表示 */} </div> ) }
挙動を確認したところ、どれだけNoteを追加しても一覧に反映されないという事象に遭遇しました。
原因
Next13ではRouteページはデフォルトでStatic Renderingになるようです。(公式)
要はビルド時に生成したHTMLを各リクエスト時に再利用されるということです。
さらに、fetchAPIはcacheのオプションを何も付与しなければ、force-cacheオプションが付与されるのと同様の挙動になるとのことです。
そのため、ビルド後当該ページにアクセスしてもNote取得の処理が走らず、レコードが追加されたところで一覧には表示されない、という事象が起こっていました。
ちなみにStaticであることは、ビルド時の出力で確認することが可能です。(/notesにはStaticを意味する○がついています。)
terminalRoute (app) Size First Load JS ┌ ○ / 5.3 kB 78.9 kB ├ λ /api/notes 0 B 0 B (略) ├ ○ /notes 6.21 kB 90.3 kB (略) λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps) ○ (Static) automatically rendered as static HTML (uses no initial props)
解決
Route Segment Configを指定することで解決しました。
いくつか方法はあるようですが、今回はrevalidate = 0を指定することで、ページアクセス時に常にfetchが実行されるようにしました。
(fetchAPIのcacheオプションにno-storeを指定した状態)
app/notes/page.tsxexport const revalidate = 0; export default async function Page() { const notes = await getNotes(); return ( <div> {/* Note一覧を表示 */} </div> ) }
再度ビルド時の出力を確認すると、Serverになっていることが分かるかと思います。
terminalRoute (app) Size First Load JS ┌ ○ / 5.3 kB 78.9 kB ├ λ /api/notes 0 B 0 B (略) ├ λ /notes 6.21 kB 90.3 kB (略) λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps) ○ (Static) automatically rendered as static HTML (uses no initial props)
ちなみにrevalidateに任意の数値を指定することもでき、そうすると指定した時間以後にリクエストがあった際にページを再生成するような挙動になるようです。
終わりに
ドキュメントを読むことの大切さを感じる日々です。
読んでいく中で技術力だけでなく、英語力も向上されるとさらに嬉しいですね。