web-dev-qa-db-ja.com

React一致しない場合のルーターv4リダイレクト

反応するルーター(および一般的にクライアント側のルーティング)が初めてなので、これについてすべて間違っていると思うかもしれません。その場合は事前に申し訳ありません...

基本的には、3つの単純なルールを実装するだけです。

  • ユーザーがいない場合は、「/ login」にリダイレクトします
  • それ以外の場合、ルートが存在しない場合は、「/」(ルート)にリダイレクトします
  • それ以外の場合、ユーザーは要求されたルートに移動できます

this.state.userでユーザーを追跡します。私の現在のルーターは最初の2つの規則に従っているようですが、認証されたユーザーにのみホームページを表示させます(「/ profile」は「/」にリダイレクトします)。

 <Router>
    {this.state.user ? (
      <Switch>
        <Route path="/" exact component={Home}/>
        <Route path="/profile" exact component={Profile}/>
        <Route render={() => (<Redirect to="/" />)}/>
      </Switch>
    ) : (
      <Switch>
        <Route path="/login" exact component={Login}/>
        <Route render={() => (<Redirect to="/login" />)}/>
      </Switch>
    )}
 </Router>

どんなアドバイスも大歓迎です。ありがとうございました

7
Egor

いずれのルートも一致しない場合にリダイレクトする方法を探してここに到着した場合:

<Switch>
  // ... your routes
  <Route render={() => <Redirect to="/" />} />
</Switch>

ルートは<Switch>の直接の子である必要があることに注意してください。これは機能しません:

<Switch>
  <Fragment>
    // ... your routes
    <Route render={() => <Redirect to="/" />} />
  </Fragment>
</Switch>

(react-routerの最新バージョンで修正されている可能性があります)

12
GG.

答えは簡単です

<Switch>
  <Route path="/login" exact component={Login}/>
  {!this.state.user && <Redirect to='/login' />}
  <Route path="/" exact component={Home}/>
  <Route path="/profile" exact component={Profile}/>
  <Redirect to="/" />
</Switch>

スイッチとルーターの主な違いは、ルーターが一致したすべてのパスを実行してコンテンツを一緒に追加しようとし、最初の一致でスイッチが停止することです。

私のアプリにも同様のアプローチがありますが、保護されたルーティングを別のファイルにラップし、ユーザープロファイルをHOCとしてラップします

export const App = () => (
  <Switch>
    <Route exact path='/login' component={Login} />
    {!hasToken() && <Redirect to='/login' />}
    <Route path='/' component={ProtectedRoute} />
  </Switch>
)

protectedRoute.js

const ProtectedRoute = ({ userInfo }: Props) => (
  <Layout userInfo={userInfo}>
    <Switch>
      <Route exact path='/a' component={A} />
      <Route exact path='/b' component={B} />
      <Route path='/c' component={C} />
      <Redirect to='/a' />
    </Switch>
  </Layout>
)

export default withUserInfo(ProtectedRoute)
4
Mark Lai

ユーザーがRouteに必要なときにユーザーをチェックするRouteラッパーを使用することを考えましたか?

const CanHasRouteAccess = ({ component: Component, iHasUser, ...rest }) => {
  return iHasUser ? (
    <Route {...rest} render={props => <Component {...props} />} />
  ) : (
    <Redirect to="/" />
  );
};

ルートに小道具を渡すことも、ユーザーがいないときにホームページにリダイレクトすることもできます。

<CanHasRouteAccess
  path="/personal-data"
  exact
  component={Profile}
  iHasUser={Boolean(user)}
  />
2
Ryan