web-dev-qa-db-fra.com

Comment utiliser React Fonction de redirection du routeur?

Je veux configurer le routeur React de la manière suivante. Si une certaine route correspond, l'utilisateur est redirigé vers une autre. Documentation indique que c'est possible, mais ne le fait pas 't fournir le moyen exact d'y parvenir. Quelqu'un at-il un aperçu à ce sujet?

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

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

[~ # ~] modifier [~ # ~] Voir une autre réponse pour une nouvelle syntaxe de routeur de réaction non obsolète =


Il y a un bon exemple de la façon d'utiliser le hook onEnter dans le exemple auth-flow . Voici le code pertinent:

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'))

Comme vous pouvez le voir, lorsque le /dashboard route est accessible la fonction requireAuth est appelée. Il reçoit deux arguments: nextState, qui est un objet RouterState qui représente l'état que l'utilisateur est sur le point d'entrer, et replaceState, a - RedirectFunction qui peut être appelé pour remplacer cet état par autre chose. Dans ce cas, si l'utilisateur n'est pas connecté, requireAuth appelle replaceState comme ceci:

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

Le deuxième argument est évidemment le chemin d'accès vers lequel l'utilisateur sera redirigé. Le tout premier argument est un objet qui peut contenir toutes les données que nous voulons que le gestionnaire d'itinéraire (dans ce cas, le composant Login) ait. Ici, le chemin d'accès auquel l'utilisateur tentait d'accéder (/dashboard) est définie comme la propriété nextPathname, donc après la connexion, l'utilisateur peut être redirigé vers cette page (voir la méthode handleSubmit dans le composant Login).

Si l'utilisateur est connecté, requireAuth ne fait rien, et puisque replaceState n'est jamais appelé, la route fonctionne comme d'habitude, c'est-à-dire que le composant Dashboard est rendu.

37
Jordan Running

Attention à tous ceux qui lisent cette question depuis react-router 2.0.0, replaceState (état, chemin d'accès, requête) est désormais obsolète. Vous devez maintenant utiliser à la place replace (location) par un descripteur d'emplacement.

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

De leur guide:

// 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

Voici un exemple de procédure à suivre avec react-router 2.0.0 (en utilisant replace au lieu de replaceState):

Dans 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>
);

Ensuite, à l'intérieur du composant SignIn, vous pouvez rediriger après une connexion réussie comme ceci:

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