web-dev-qa-db-ja.com

Reactルーターリダイレクト関数を使用するには?

Reactルーターを次のように構成します。特定のルートが一致した場合、ユーザーは別のルートにリダイレクトされます。 Documentation それは可能であると述べていますが、それを達成するための正確な方法を提供していません。

type EnterHook = (nextState: RouterState, replaceState: RedirectFunction, callback?: Function) => any;

type RedirectFunction = (state: ?LocationState, pathname: Pathname | Path, query: ?Query) => void;
22
JD.

[〜#〜] edit [〜#〜]新しい、非推奨ではない反応ルーター構文については他の回答を参照してください


auth-flow exampleonEnterフックを使用する方法の良い例があります。関連するコードは次のとおりです。

function requireAuth(nextState, replaceState) {
  if (!auth.loggedIn())
    replaceState({ nextPathname: nextState.location.pathname }, '/login')
}

render((
  <Router history={history}>
    <Route path="/" component={App}>
      <Route path="login" component={Login} />
      <Route path="logout" component={Logout} />
      <Route path="about" component={About} />
      <Route path="dashboard" component={Dashboard} onEnter={requireAuth} />
    </Route>
  </Router>
), document.getElementById('example'))

ご覧のとおり、/dashboardルートがアクセスされ、requireAuth関数が呼び出されます。 2つの引数を受け取ります:nextStateはユーザーが入力しようとしている状態を表す RouterState オブジェクトであり、replaceStateは- RedirectFunction これは、その状態を別のものに置き換えるために呼び出すことができます。この場合、ユーザーがログインしていない場合、requireAuthreplaceStateを次のように呼び出します。

replaceState({ nextPathname: nextState.location.pathname }, '/login')

2番目の引数は、明らかにユーザーがリダイレクトされるパス名です。最初の引数は、ルートハンドラー(この場合はLoginコンポーネント)に必要なデータを含むことができるオブジェクトです。ここで、ユーザーが移動しようとしていたパス名(/dashboard)はnextPathnameプロパティとして設定されるため、ユーザーのログイン後にそのページにリダイレクトできます(handleSubmitコンポーネントのLoginメソッドを参照)。

ユーザーがログインしている場合、requireAuthは何も行いません。また、replaceStateが呼び出されることはないため、ルートは通常どおり機能します。つまり、Dashboardコンポーネントがレンダリングされます。

37
Jordan Running

React-router 2.0.0の時点でこの質問を読んでいるすべての人に向かって、replaceState(state、pathname、query)は非推奨になりました。代わりに、場所記述子でreplace(location)を使用する必要があります。

https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md#link-to-onenter-and-isactive-use-location-descriptors

彼らのガイドから:

// v1.0.x
(nextState, replaceState) => replaceState(null, '/foo')
(nextState, replaceState) => replaceState(null, '/foo', { the: 'query' })

// v2.0.0
(nextState, replace) => replace('/foo')
(nextState, replace) => replace({ pathname: '/foo', query: { the: 'query' } })
16
Danny

react-router 2.0.0でこれを行う方法の例を次に示します(replaceの代わりにreplaceStateを使用):

router.jsx

function requireAuth(nextState, replace) {
  if (!userExists()) {
    replace({
      pathname: '/signin',
      state: { nextPathname: nextState.location.pathname }
    })
  }
}

export const renderRoutes = () => (
  <Router history={browserHistory}>
      <Route path="protectedRoute" component={Protected} onEnter={requireAuth} />
      <Route path="signin" component={SignIn} />
    </Route>
  </Router>
);

次に、SignInコンポーネント内で、次のようにサインインに成功した後にリダイレクトできます。

import { browserHistory } from 'react-router';

signInFunction({params}, (err, res) => {
  // Now in the sign in callback
  if (err)
    alert("Please try again")
  else {
    const location = this.props.location
    if (location.state && location.state.nextPathname) {
      browserHistory.Push(location.state.nextPathname)
    } else {
      browserHistory.Push('/')
    }
  }
})
10
justswim