実装背景
Next.jsのAppRouterを使用してserver actionでredirectを行うと、リダイレクト先のページで成功や失敗のメッセージを表示することが難しくなります。
これは、リダイレクトが発生すると、現在のページの状態がリセットされ、新しいページが読み込まれるためです。
これを解決するために、一度だけ表示するメッセージを保存する方法としてcookieを使用します。
サンプルリポジトリはこちら
https://github.com/yuyakinjo/next-app-flash
動作動画(a
タグバージョン)
注意: /
ページで表示されている、/flash
ページのリンクはa
タグを使用しています
なぜa
タグを使っているかは後述します。
流れ
-
/
ページ -
/form
ページで、入力 - 入力後、
/flash
ページへリダイレクト -
flash
という名前のcookie
があれば、success
という文字を表示 - 一度、別のページに遷移したり、リロードすると文字が消える
ページ概要
-
/
ページ: 各ページへリンクがあるページ -
/form
ページ: フォームを入力し、formにはserver actionが設定されている。フォーム送信完了後はflash
ページへリダイレクト -
/flash
ページ: flash表示ページ
cookiesを使う
cookiesは、nextjsが用意している関数で、maxAge(秒)
を0
にすることで、リダイレクト後、一度だけ取得でき、すぐ消滅してくれるので削除する必要もありません。
Railsではflashと呼ばれています。
備考として、cookiesを使用すると、ページは毎回動的レンダリングになるはず。。。
あれ動的レンダリングされてなさそう
cookiesは動的関数で、それを使っているページは毎回動的レンダリングされ、キャッシュされないはずだけど、キャッシュされてるぞ!!!
この表でいう、一番下じゃないのか。cookieもキャッシュされる対象になっているのかな。。。
もしかしたら、下記のドキュメントかもしれないけど、どこがそれに抵触する箇所なのか難しい
https://nextjs.org/docs/app/building-your-application/caching#full-route-cache
Linkコンポーネント使うと、cookieの値もキャッシュされて表示されちゃうよ
nextjsのlearnでもやるのですが、Linkコンポーネントはnextjsが用意してくれているprefetch(移動先のページをあらかじめ読み込んでくれてたり)をハンドリングできるコンポーネントなのですが、これが相性よくなかったみたいです。
a
タグ使うと、毎回ページを読みに行きますのでやりたかった動きが叶いました。
Linkコンポーネントでも、cookie自体はブラウザからちゃんと消えてくれてます。
動作動画(Linkコンポーネントバージョン)
注意: /
ページで表示されている、/flash
ページのリンクはLinkコンポーネントを使用しています
まとめ
リダイレクト後に、一度だけ表示したい(flash
)は叶いましたが、flash
を実装したページのリンク先には、a
タグを使わないと、cookieの値もキャッシュされちゃうので気をつけてください。