【Inertia】ブラウザバックでrouterでの自動更新を行う
こんにちは、フリーランスエンジニアの太田雅昭です。
Inertiaでのデータ更新周り
Inertiaでは、主にusePageでデータを処理します。これはレンダリング時にサーバーから直接データをもらえるので、便利です。
ところが色々な問題もあります。今回はブラウザバック周りの問題をあげます。
サーバーでリダイレクトしてみる
アイテムリストを表示しているページから、新しくデータを作成する時に、サーバーサイドで以下のようにリダイレクトしたとします。
public function store(Request $request)
{
...
return to_route('xxx.show', $xxx);
}
無事新しいデータのページにリダイレクトされるのですが、ここからブラウザバックで戻ると、データが更新されず、古い状態の表示がされてしまいます。せっかくデータを追加したのに、追加されていないかのようになってしまいます。
リダイレクトをなくしてみる
それを防ぐため、リダイレクトをなくしてみます。
public function store(Request $request)
{
...
return back();
}
これで、新しくデータを追加したことがアイテムリストに反映されます。場合によってはこれで良いのですが、paginationを使っていると、例えば2ページ目を表示している時にアイテムを追加すると、追加されたアイテムが表示されないといった事象が発生します。
リダイレクトした上で、ブラウザバック時にリロードしてみる
そこで以下のように、ブラウザバック時に自動で更新するようにしてみます。
window.addEventListener('popstate', ()=>{
window.location.reload();
});
これで、新しく追加したデータのページに移動した上で、ブラウザバックした時には自動更新されるようになりました。ユーザー体験にはだいぶ向上したかと思います。ですが更新表示がスムーズではないため、inertiaの機能でリロードしてみます。
window.addEventListener('popstate', ()=>{
router.reload();
});
これで良いはず。。。と思ったのも束の間、正常にブラウザバックできません。これは困りました。これまでにあげてきた方法のどれかを選ばないといけないのか、しばらく頭を悩ませていたのですが、以下のようにすることで解決しました。
リダイレクトした上でブラウザバック時にsetTimeoutでInertiaリロードする
window.addEventListener('popstate', ()=>{
setTimeout(()=>{
router.reload();
}, 10);
});
setTimeoutでスレッドを変更することで、routerでも正常にリロードできるようになりました。