Context APIかRedux等を使って値を保持しようしたら、毎回初期化されたので原因を調べました。
その過程で、遷移時に画面全体が書き変わっている(普通の遷移やリロードと同じ状態)になっている事に気付いたので、メモしておきます。
状態
画面全体が書き換わる
リンクやリンクのボタンクリック時に、コンソールやネットワークが初期化される。
期待値:DOMが書き換わる
リンクやリンクのボタンクリック時に、コンソールやネットワークが初期化されない。
書き換える箇所のみ取得される。
原因
Material UIのLinkだけを使ってしまった為、AppRouterCacheProviderが効かなかった。
こちらでデザインは適用されますが、普通のaリンクの挙動でNextLinkではないので、DOMの書き換えは行われない。なので、hrefはNextLinkで渡してあげる必要がある。
暫定対応
src/app/components/SignUp.tsx
+ import NextLink from 'next/link'
import Link from '@mui/material/Link'
- <Link href="/users/sign_in">{t('ログイン')}</Link>
+ <NextLink href="/users/sign_in" passHref legacyBehavior>
+ <Link>{t('ログイン')}</Link>
+ </NextLink>
Buttonでhrefを渡す場合も同様にNextLinkにする必要がある。
+ import NextLink from 'next/link'
import Button from '@mui/material/Button'
- <Button href="/users/sign_up" variant="contained">{t('無料で始める')}</Button>
+ <NextLink href="/users/sign_up" passHref legacyBehavior>
+ <Button variant="contained">{t('無料で始める')}</Button>
+ </NextLink>
passHref
Forces 'Link' to send the 'href' property to its child. Defaults to 'false'
リンクに href プロパティを子に送信するよう強制します。デフォルトは false です。
legacyBehavior
An '<a>' element is no longer required as a child of '<Link>'. Add the 'legacyBehavior' prop to use the legacy behavior or remove the '<a>' to upgrade. A codemod is available to automatically upgrade your code.
<a> 要素は、<Link> の子として必要ではなくなりました。 legacyBehavior プロパティを追加して従来の動作を使用するか、<a> を削除してアップグレードしてください。 コードを自動的にアップグレードするための codemod が利用可能です。
未設定の場合、下記Warningが出ます。
Warning: Expected server HTML to contain a matching <a> in <a>.
恒久対応
componentでNextLinkを渡してあげるだけでOKだった。
+ import NextLink from 'next/link'
import Link from '@mui/material/Link'
import Button from '@mui/material/Button'
<Link
+ component={NextLink}
href="/users/sign_in"
>
{t('ログイン')}
</Link>
<Button
+ component={NextLink}
href="/users/sign_up"
variant="contained"
>
{t('無料で始める')}
</Button>