web-dev-qa-db-fra.com

Comment faire une redirection vers un autre itinéraire avec react-router?

J'essaye de faire un SIMPLE en utilisant react-router (version ^ 1.0.) pour rediriger vers une autre vue et je commence juste à être fatigué.

import React from 'react';
import {Router, Route, Link, RouteHandler} from 'react-router';


class HomeSection extends React.Component {

  static contextTypes = {
    router: PropTypes.func.isRequired
  };

  constructor(props, context) {
    super(props, context);
  }

  handleClick = () => {
    console.log('HERE!', this.contextTypes);
    // this.context.location.transitionTo('login');
  };

  render() {
    return (
      <Grid>
        <Row className="text-center">          
          <Col md={12} xs={12}>
            <div className="input-group">
              <span className="input-group-btn">
                <button onClick={this.handleClick} type="button">
                </button>
              </span>
            </div>
          </Col>
        </Row>
      </Grid>
    );
  }
};

HomeSection.contextTypes = {
  location() {
    React.PropTypes.func.isRequired
  }
}

export default HomeSection;

tout ce dont j'ai besoin est d’envoyer l’utilisation à '/ login' et le tour est joué.

Que puis-je faire ?

erreurs dans la console:

Uncaught ReferenceError: PropTypes n'est pas défini

déposer avec mes itinéraires

// LIBRARY
/*eslint-disable no-unused-vars*/
import React from 'react';
/*eslint-enable no-unused-vars*/
import {Route, IndexRoute} from 'react-router';

// COMPONENT
import Application from './components/App/App';
import Contact from './components/ContactSection/Contact';
import HomeSection from './components/HomeSection/HomeSection';
import NotFoundSection from './components/NotFoundSection/NotFoundSection';
import TodoSection from './components/TodoSection/TodoSection';
import LoginForm from './components/LoginForm/LoginForm';
import SignupForm from './components/SignupForm/SignupForm';

export default (
    <Route component={Application} path='/'>
      <IndexRoute component={HomeSection} />
      <Route component={HomeSection} path='home' />
      <Route component={TodoSection} path='todo' />
      <Route component={Contact} path='contact' />
      <Route component={LoginForm} path='login' />
      <Route component={SignupForm} path='signup' />
      <Route component={NotFoundSection} path='*' />
    </Route>
);
68
Reacting

Pour une réponse simple, vous pouvez utiliser le composant Link de react-router au lieu de button. Il existe des moyens de changer de route dans JS, mais il semble que vous n'en ayez pas besoin ici.

<span className="input-group-btn">
  <Link to="/login" />Click to login</Link>
</span>

Pour le faire par programme dans 1.0.x, vous procédez comme suit dans votre fonction clickHandler:

this.history.pushState(null, 'login');

Tiré de la documentation de mise à niveau ici

Vous devez avoir this.history placé sur votre composant de gestionnaire d'itinéraire par react-router. S'il s'agit d'un composant enfant situé en dessous de celui mentionné dans la définition de routes, vous devrez peut-être le transmettre plus tard.

23
aarosil

1) react-router> V4 vous pouvez utiliser withRouter HOC:

Comme @ambar l'a mentionné dans les commentaires, React-router a modifié sa base de code depuis sa V4. Voici les documentations - official , withRouter

import React, { Component } from 'react';
import { withRouter } from "react-router-dom";

class YourComponent extends Component {
    handleClick = () => {
        this.props.history.Push("path/to/Push");
    }

    render() {
        return (
          <Grid>
            <Row className="text-center">          
              <Col md={12} xs={12}>
                <div className="input-group">
                  <span className="input-group-btn">
                    <button onClick={this.handleClick} type="button"></button>
                  </span>
                </div>
              </Col>
            </Row>
          </Grid>
        );
      }
    };
}

export default withRouter(YourComponent);

2) React-router <V4

Vous pouvez obtenir cette fonctionnalité en utilisant react-router BrowserHistory. Code ci-dessous:

import React, { Component } from 'react';
import { browserHistory } from 'react-router';

export default class YourComponent extends Component {
    handleClick = () => {
        browserHistory.Push('/login');
    };

    render() {
        return (
          <Grid>
            <Row className="text-center">          
              <Col md={12} xs={12}>
                <div className="input-group">
                  <span className="input-group-btn">
                    <button onClick={this.handleClick} type="button">
                    </button>
                  </span>
                </div>
              </Col>
            </Row>
          </Grid>
        );
      }
    };
}

3) Avec redux connected-react-router

Si vous avez connecté votre composant avec redux et avez configuré connected-react-router , tout ce que vous avez à faire est de this.props.history.Push("/new/url"); c'est-à-dire que vous n'avez pas besoin de withRouter HOC pour injecter history aux accessoires du composant.

// reducers.js
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';

export default (history) => combineReducers({
    router: connectRouter(history),
    ... // rest of your reducers
});


// configureStore.js
import { createBrowserHistory } from 'history';
import { applyMiddleware, compose, createStore } from 'redux';
import { routerMiddleware } from 'connected-react-router';
import createRootReducer from './reducers';
...
export const history = createBrowserHistory();

export default function configureStore(preloadedState) {
    const store = createStore(
        createRootReducer(history), // root reducer with router state
        preloadedState,
        compose(
            applyMiddleware(
                routerMiddleware(history), // for dispatching history actions
                // ... other middlewares ...
            ),
        ),
    );

    return store;
}


// set up other redux requirements like for eg. in index.js
import { Provider } from 'react-redux';
import { Route, Switch } from 'react-router';
import { ConnectedRouter } from 'connected-react-router';
import configureStore, { history } from './configureStore';
...
const store = configureStore(/* provide initial state if any */)

ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <> { /* your usual react-router v4/v5 routing */ }
                <Switch>
                    <Route exact path="/yourPath" component={YourComponent} />
                </Switch>
            </>
        </ConnectedRouter>
    </Provider>,
    document.getElementById('root')
);


// YourComponent.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
...

class YourComponent extends Component {
    handleClick = () => {
        this.props.history.Push("path/to/Push");
    }

    render() {
        return (
          <Grid>
            <Row className="text-center">          
              <Col md={12} xs={12}>
                <div className="input-group">
                  <span className="input-group-btn">
                    <button onClick={this.handleClick} type="button"></button>
                  </span>
                </div>
              </Col>
            </Row>
          </Grid>
        );
      }
    };

}

export default connect(mapStateToProps = {}, mapDispatchToProps = {})(YourComponent);
45
Noushad

Comment faire une redirection vers un autre itinéraire avec react-router?

Par exemple, lorsqu'un utilisateur clique sur un lien <Link to="/" />Click to route</Link> réagit-routeur recherchera / et vous pourrez utiliser Redirect to et envoyer l'utilisateur ailleurs, comme la route de connexion.

Depuis le docs pour ReactRouterTraining :

Le rendu d'un <Redirect> va accéder à un nouvel emplacement. Le nouvel emplacement remplacera l'emplacement actuel dans la pile d'historique, comme le font les redirections côté serveur (HTTP 3xx).

import { Route, Redirect } from 'react-router'

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

to: string, L'URL vers laquelle rediriger.

<Redirect to="/somewhere/else"/>

to: objet, un emplacement vers lequel rediriger.

<Redirect to={{
  pathname: '/login',
  search: '?utm=your+face',
  state: { referrer: currentLocation }
}}/>
16
jtlindsey

Avec react-router v2.8.1 (probablement d'autres versions 2.x.x également, mais je ne l'ai pas testée), vous pouvez utiliser cette implémentation pour effectuer une redirection de routeur.

import { Router } from 'react-router';

export default class Foo extends Component {

  static get contextTypes() {
    return {
      router: React.PropTypes.object.isRequired,
    };
  }

  handleClick() {
    this.context.router.Push('/some-path');
  }
}
5
Tom Van Rompaey