📝

React Routerで条件に応じてリダイレクト

2022/10/11に公開

概要

React Router で各ルーティングの設定を書くときに、「認証してなかったら/login にリダイレクト」みたいな処理を書くためのメモです。

起きた問題

とある学習用に公開されているソースコードをクローンした際、以下のような書き方がされていました。

src/routes/Router.jsx
import { BrowserRouter, Routes, Route, Redirect } from "react-router-dom";

const Router = () => {
    //loggedInにログイン情報 (ログインしてればtrueそうでなければfalse) が格納されている
  const loggedIn = useSelector((state) => state.auth.isSignIn);

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/signin" element={<SignIn />} />
        {loggedIn ? (
          <>
            <Route path="/" element={ <Home /> }/>
          </>
        ) : (
          <Route>
            <Redirect to="/signin" />
          </Route>
        )}
      </Routes>
    </BrowserRouter>
  );
}

export default Router;

上記のままだとおそらくこんなエラーが出ます。

export 'Redirect' (imported as 'Redirect') was not found in 'react-router-dom'

その理由はこちら ↓
https://gist.github.com/mjackson/b5748add2795ce7448a366ae8f8ae3bb
React Router バージョン6以降では非推奨。というか今回実際 import できなかった。

なので以下のように書き換えてみます。

src/routes/Router.jsx
import {・・・省略, Navigate} from "react-router-dom";
//・・・省略
<Routes>
//・・・省略
  <Route>
    <Navigate replace to="/signin" />
  </Route>
</Routes>

すると、今度はこんなエラーが出ます。

Uncaught Error: [Navigate] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>

<Routes>の children は<Route><React.Fragment>しかダメみたいです。

解決策 (結論)

以下のように、<Route>タグのelementプロパティの値に三項演算子を用いて分岐させる。

src/routes/Router.jsx
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";

const Router = () => {
    //loggedInにログイン情報 (ログインしてればtrueそうでなければfalse) が格納されている
  const loggedIn = useSelector((state) => state.auth.isSignIn);

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/signin" element={<SignIn />} />
        <Route path="/" element={ loggedIn ? <Home /> : <Navigate replace to="/signin" />}/>
      </Routes>
    </BrowserRouter>
  );

export default Router;

でも、ルートの数が増えるとこれ一々書くの面倒だから、他の書き方の方がいい気もする、、。

他にいい書き方あればぜひ教えてください。

GitHubで編集を提案

Discussion