Open4

App Router の template.js の挙動の調査

かしかし

こういうのを作ってみた。
https://github.com/tnyo43/test-template

template.js には時刻を表示した時の時刻を持たせているので、時刻が更新されることをもって state がリセットされたことを検知できる。

ファイル構成はこんな感じ

- app
|- tempate.jsx
|- page1 - page.jsx
|- page2 - page.jsx
|- group1
|   |- template.jsx
|   |- page1 - page.jsx
|   `- page2 - page.jsx
|- group2
|   |- layout.jsx
|   |- page1 - page.jsx
|   `- page2 - page.jsx
`- group3
    |- layout.jsx
    |- template.jsx
    |- page1 - page.jsx
    `- page2 - page.jsx
かしかし

/(root) -> /page1 に移動した場合はリセットされる

root /page1

/page1 -> /group1/page1 に移動した場合はリセットされる。また、 /group1/page1 の template.js の state も新たにセットされる

/page1 /group1/page1

/group1/page1 -> /group1/page2 に移動した場合は、ルートの方の template の状態はそのままで、 group1 の template の state のみがリセットされる。

/page1 /group1/page1

/group1/page2 -> /group2/page1 に移動した場合もリセットするが、 /group2/page1 -> /group2/page2 に移動した場合はリセットしない。

navigation によって直接の子が切り替わるタイミングでリセットされるけど、子に layout や他の template がある場合はリセットされないっぽい?

かしかし

navigation によって直接の子が切り替わるタイミングでリセットされるけど、子に layout や他の template がある場合はリセットされないっぽい?

この認識は違いそう。
https://github.com/vercel/next.js/issues/52422

I tested the code and it seems templates just don't rerender on navigation wether in route groups or not

あたらしく /group4 を作って layout.js や template.js を追加せずに /page1/page2 を追加したが、この間のページ遷移でもリセットしなかった。

root /page1
  • template.js の直接の子が更新されるような遷移をした場合のみ state をリセットする
  • 遷移するページ間で共通の group がある場合は、それよりも上の template.js はリセットされない

という挙動で正しそう。