462 文字
2 分

Q. React-RouterでURLをリダイレクトさせたら元のページに戻れなくなった。

リダイレクトさせるときに 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
Q. React-RouterでURLをリダイレクトさせたら元のページに戻れなくなった。
https://blog.ohirunewani.com/posts/react-router-redirect-url-replace/
作者
hrdtbs
公開日
2020-04-08
ライセンス
CC BY-NC-SA 4.0