javascript - Cum să faci o redirecționare către o altă rută cu react-router?
Încerc să fac UN LUCRU SIMPLU folosind react-router ( versiunea ^1.0.3 ) pentru a redirecționa către o altă vizualizare.
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;
Tot ce am nevoie este să trimit utilizatorul la '/login' și atât.
Ce pot să fac?
erori în consolă:
Eroare de referință nerapelată: PropTypes nu este definit
fișier cu traseele mele
// 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>
);
Răspuns #1
1) react-router > V6 useNavigate hook:
Dacă ai React >= 16.8 și componente funcționale, poți folosi hook-ul useNavigate din react-router.
import React from 'react';
import { useNavigate } from "react-router-dom";
const YourComponent = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate("/path/to/push");
}
return (
<div>
<button onClick={handleClick} type="button" />
</div>
);
}
export default YourComponent;
2) react-router > V5 useHistory hook:
Dacă aveți react-router v5 și componente funcționale, puteți folosi hook-ul useHistory din react-router.
import React from 'react';
import { useHistory } from 'react-router-dom';
const YourComponent = () => {
const history = useHistory();
const handleClick = () => {
history.push("/path/to/push");
}
return (
<div>
<button onClick={handleClick} type="button" />
</div>
);
}
export default YourComponent;
3) react-router > V4 withRouter HOC:
Așa cum a menționat @ambar în comentarii, React-router și-a schimbat baza de cod de la versiunea V4. Iată documentația pentru 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 (
<div>
<button onClick={this.handleClick} type="button">
</div>
);
};
}
export default withRouter(YourComponent);
4) React-router < V4 cu browserHistory
Poți realiza această funcționalitate folosind BrowserHistory din react-router. Codul de mai jos:
import React, { Component } from 'react';
import { browserHistory } from 'react-router-dom';
export default class YourComponent extends Component {
handleClick = () => {
browserHistory.push('/login');
};
render() {
return (
<div>
<button onClick={this.handleClick} type="button">
</div>
);
};
}
5) Redux connected-react-router
Dacă ți-ai conectat componenta cu Redux și ai configurat connected-react-router, tot ce trebuie să faci este this.props.history.push("/new/url");, adică nu ai nevoie de HOC-ul withRouter pentru a injecta history în proprietățile componentei.
// 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-dom';
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 (
<div>
<button onClick={this.handleClick} type="button">
</div>
);
}
};
}
export default connect(mapStateToProps = {}, mapDispatchToProps = {})(YourComponent);
Răspunsul #2
Pentru un răspuns simplu, poți folosi componenta Link din react-router, în loc de button. Există modalități de a schimba ruta în JS, dar se pare că aici nu ai nevoie de asta.
<span className="input-group-btn">
<Link to="/login">Click to login</Link>
</span>
Pentru a face acest lucru programatic în 1.0.x, procedezi astfel, în interiorul funcției tale clickHandler:
this.history.pushState(null, 'login');Preluat din documentul de actualizare de aici
Ar trebui să aveți this.history plasat pe componenta de handler a rutei de către react-router. Dacă este o componentă copil sub cea menționată în definiția routes, s-ar putea să fie nevoie să o transmiteți mai departe.
Răspunsul #3
Cum să faci o redirecționare către o altă rută cu react-router?
De exemplu, când un utilizator face clic pe un link <Link to="/" />Click to route</Link>, react-router va căuta / și poți folosi Redirect to și să trimiți utilizatorul în altă parte, cum ar fi ruta de autentificare.
Din documentația pentru ReactRouterTraining:
Redarea unui
<Redirect>va naviga către o locație nouă. Noua locație va suprascrie locația curentă din stiva istoriei, așa cum fac redirecționările pe partea serverului (HTTP 3xx).
import { Route, Redirect } from 'react-router'
<Route exact path="/" render={() => (
loggedIn ? (
<Redirect to="/dashboard"/>
) : (
<PublicHomePage/>
)
)}/>
către: șir, URL-ul către care se redirecționează.
<Redirect to="/somewhere/else"/>
către: obiect, O locație către care să redirecționați.
<Redirect to={{
pathname: '/login',
search: '?utm=your+face',
state: { referrer: currentLocation }
}}/>
Răspunsul #4
Cea mai simplă soluție pentru web!
Actualizat până în 2020
confirmat că funcționează cu:
"react-router-dom": "^5.1.2"
"react": "^16.10.2"
Folosește hook-ul useHistory()!
import React from 'react';
import { useHistory } from "react-router-dom";
export function HomeSection() {
const history = useHistory();
const goLogin = () => history.push('login');
return (
<Grid>
<Row className="text-center">
<Col md={12} xs={12}>
<div className="input-group">
<span className="input-group-btn">
<button onClick={goLogin} type="button" />
</span>
</div>
</Col>
</Row>
</Grid>
);
}
Răspunsul #5
Știu că aceasta este o întrebare veche, dar pentru oricine ajunge aici în 2021 și după, începând cu React Router V6, useHistory nu mai este exportat din react-router-dom și trebuie să importați useNavigate în schimb. Codul de exemplu este mai jos:
import { useNavigate } from "react-router-dom"
și în interiorul clasei tale React sau al componentei funcționale:
const navigate = useNavigate()
navigate("/404")
Răspunsul #6
Cu react-router v2.8.1 (probabil și alte versiuni 2.x.x, dar nu le-am testat) poți folosi această implementare pentru a face un redirect în Router.
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');
}
}
