Q. React-RouterでURLをリダイレクトさせたら元のページに戻れなくなった。
React-Routerでリダイレクトさせる際にreplaceさせないと、リダイレクトされるページの前にいたページに戻れなくなるのは当たり前だと思うが、質問があったのでまとめた。
リダイレクトさせるときにreplaceさせないと、リダイレクトされるページの前にいたページへ戻れなくなるのは当たり前だと思うが、質問があったのでまとめた。“元のページ”は”リダイレクトが発生するページ”なのか、“リダイレクトが発生するページの前にいたページ”なのかで認識に齟齬があり説明に難儀した。
リダイレクトする際にreplaceさせないと元のページにブラウザのバックボタンから戻れなくなる。
たとえば /shop/list
と/shop/items/:itemid
のようなURLを考える。
/shop
やそれ以下の存在しないURLにアクセスすると/list
にリダイレクトされるようなRoutesを定義し、ItemPageからはいつでもlistページに戻れるようなボタンを設置した。ただしこのときlistページのURLは変更される可能性があったため、あえてリダイレクトを前提としたnavigate("/shop")
のような記述をした。
const ItemPage = () => {
return (
<Button
onClick={() => {
navigate("/shop");
}}
>
Back to List
</Button>
);
};
const routes: RouteObject[] = [
{
path: "/list",
element: <ListPage />,
},
{
path: "/items/:itemId",
element: <ItemPage />,
},
{
path: "*",
element: <Navigate to="list" />,
},
];
この状況で、ItemPageからListPageに戻ると、ブラウザのバックボタンでListPageから離脱できなくなる。 これはhistoryが以下のようになっているためである。
0: /shop/items/0
1: /shop/items/1
2: /shop
3: /shop/list
この状況でブラウザバックをすると2のURL/shop
にアクセスしようとするため、その度に/shop/list
ページへリダイレクトすることになる。
const routes: RouteObject[] = [
{ path: "*", element: <Navigate to="list" replace /> },
];
replaceを付けておくことで、この状況は回避できる。replaceを付けておけばhistoryは以下のようになるため/shop/items/1
へ戻ることができるようになる。
0: /shop/items/0
1: /shop/items/1
2: /shop/list