実装背景
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の値もキャッシュされちゃうので気をつけてください。


