【React】react-router-domに認証状態に応じて、遷移先を切り替える方法

<h2>認証状態に応じて、遷移先を変えたい</h2>

eract-router-domを使用したアプリで、ログインしているかどうかで、遷移させたい画面と遷移させたくないが面が出てくると思います。
今回は一つの回答として、その切り替え方について、紹介していきます。

<h2>実装方法</h2>
まず、大本となるAPP.jsが以下になります。
ここではReducerを使ってログイン状態を確認し、pathに応じたrouteを定義しています。

URLに乗せたparamsを渡す際は、Profileのrouteのようにrenderを使用します。

```App.js
import React,{ Fragment, useEffect,useReducer } from "react";
import './App.css';
import {
  BrowserRouter as Router,
  Switch,
  Route,
} from "react-router-dom";
import {isLoginApi} from "./apis/isLoginApi";
import { Home } from "./containers/Home";
import {MyPage} from "./containers/users/MyPage";
import {Profile} from "./containers/users/userProfile";
import {sessionApis} from "./apis/sessionApis";
import {initializeState,sessionActionTypes,sessionReducer} from "./reducer/sessionReducer";

function App() {
  const [state,dispatch] = useReducer(sessionReducer,initializeState);

  //ログイン情報をいい感じに取得します(割愛します)
  useEffect(() => {
    isLoginApi()
    .then((data)=>{
      dispatch({
        type:sessionActionTypes.ISLOGIN,
        payload: {
          currentUser:data.user
        },
        payload: {
          is_login:data.is_login
        },
      })
    })
    .catch((e) => console.log(e))
  },[])

  return (
    <Fragment>
    <Router>
      <Switch>
      //HOME画面(未ログイン状態でのみアクセス可能)
        <NotPrivateRoute 
          exact
          path="/home"
          component={home}>
        </NotPrivateRoute>
        //MyPage画面(ログイン済状態でのみアクセス可能)
        <PrivateRoute 
          exact
          path="/users/MyPage"
          component={page}>
        </PrivateRoute>
        //Profile画面(ログイン済状態でのみアクセス可能。paramsを渡している)
        <PrivateRoute 
          exact
          path="/users/MyPage/:userId"
          render={({match}) => 
            <Profile
              match={match}
            />
          }>
        </PrivateRoute>
      </Switch>
    </Router>
    </Fragment>
  );
}

export default App;
```

続いて、switchの中にあったPrivateRouteのファイルです。
こちらのファイルでは、isLoginの値がtrueまたはfalseでコンポーネントの切り替えをしています。

・true：指定のコンポーネントを読む
・falseまたはundefined：homeにredirect


```PrivateRoute.jsx
import React from "react";
import {
  Route,
  Redirect,
} from "react-router-dom";
import {initializeState,sessionActionTypes,sessionReducer} from "./reducer/sessionReducer";


function PrivateRoute({ component: Component}){
  const [state,dispatch] = useReducer(sessionReducer,initializeState);
  
  //isLoginの値がtrueまたはfalseでコンポーネントの切り替えをしている
  return(
  state.isLogin?
    <Route {...props}
      match={props.computedMatch}
    />
  :
    <Redirect
      to={{
        pathname: homeURL,
      }}
    />
  )
}
```

下記はNotPrivateRouteファイルです。
切り替える条件が逆になっている以外は、だいたいPrivateRouteと同様の内容です。

```NotPrivateRoute.jsx
import React from "react";
import {
  Route,
  Redirect,
} from "react-router-dom";
import {initializeState,sessionActionTypes,sessionReducer} from "./reducer/sessionReducer";


function NotPrivateRoute({ component: Component}){
  const [state,dispatch] = useReducer(sessionReducer,initializeState);
  
  //isLoginの値がtrueまたはfalseでコンポーネントの切り替えをしている
  return(
  state.isLogin?
　  <Redirect
      to={{
        pathname: "/users/MyPage",
      }}
    />
  :
    <Route {...props}
      match={props.computedMatch}
    />
  )
}
```

上記のように、isLoginの状態に応じてreturnする内容を変えて、ログイン内容と会わなければredirectさせるという処理を入れています。

公式ドキュメントの<a href="https://reactrouter.com/web/example/auth-workflow">リダイレクト認証)</a>の個所をかなり参考にしたので、詳しくはそちらをご覧ください。、



<h2>参考</h2>

https://reactrouter.com/native/example/auth-workflow

https://www.hypertextcandy.com/react-route-guard