Help us understand the problem. What is going on with this article?

React-Router v4を使って認証状態でリダイレクトする処理

More than 1 year has passed since last update.

ログインが完了したらトップページにリダイレクト、未ログインで認証が必要なページにアクセスしたらログインページへリダイレクト、という処理がある。

react-routerのv4でルーティングするとこんな形である。

App.js
import React, {Component} from 'react'
import {
  BrowserRouter as Router,
  Route, Switch
} from 'react-router-dom'

import Auth from './containers/Auth'
import Top from './containers/Top'
import Login from './containers/Login'
import Signup from './containers/Signup'
import Page from './containers/Page'

class App extends React.Component{
  render(){
    return(
      <Router>
        <Switch>
          <Route exact path="/login" component={Login}/>
          <Route exact path="/signup" component={Signup}/>
          <Auth>
            <Switch>
              <Route exact path="/" component={Top}/>
              <Route exact path="/page" component={Page}/>
            </Switch>
          </Auth>
        </Switch>
      </Router>
    )}
}

export default App

このとき、Authコンポーネントでは

1. 認証済みなら何もせず、配下のルーティングに処理をプロキシする(バケツリレーする)
2. 認証がされていない(未ログイン)なら /login ページにリダイレクトする
ということをする。

stateの props.currentUser.isLoggedIn に認証状態を保持しているとして、

components/Auth.js
import React from 'react'
import { Redirect } from 'react-router-dom'

const Auth = (props) => (props.currentUser.isLoggedIn ? props.children : <Redirect to={'/Login'}/>)

export default Auth

結果は非常にシンプルなのだが、1. のバケツリレーがうまくいかず手間取った。NG集としては、

const Auth = (props) => (props.currentUser.isLoggedIn ? <Route children={props.children} /> : <Redirect to={'/Login'}/>)
const Auth = (props) => (props.currentUser.isLoggedIn ? <Route {...props} /> : <Redirect to={'/Login'}/>)

のように、プロキシのためにRouteコンポーネントを介すべきと思っていたら、これでは認証後のページでリダイレクトループが発生してしまう。props.children自体が、App.jsでAuthコンポーネントでラップしているSwitchコンポーネントだと気づいてうまくいった。

なお、Authコンポーネントの直下は単一のコンポーネントにしておく必要がある。今回はSwitchコンポーネントが該当する。バケツリレーするprops.childrenが直下に複数のコンポーネントを持ってしまうと、renderされるコンポーネントは単一の要素でなければいけないというreactの制約に怒られてしまうからだ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした