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>
);
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.
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);
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>
);
}
};
}
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);
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 }
}}/>
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');
}
}