Próbuję zrobić PROSTE za pomocą routera reaktywnego ( wersja ^ 1.0.3 ), aby przekierować do innego widoku i po prostu się męczę.
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;
wszystko, czego potrzebuję, to wysłać użycie do '/ login' i to wszystko.
Co mogę zrobić ?
błędy w konsoli:
Uncaught ReferenceError: PropTypes nie jest zdefiniowany
plik z moimi trasami
// 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>
);
javascript
reactjs
Reagowanie
źródło
źródło
routes
definicje, a także jeśli jest powód, dla którego nie używaszLink
komponentu? Wspomnij też, jakie błędy otrzymujesz.<Link to="/login">Log In</Link>
,?Uncaught ReferenceError
, wzywasz jakoPropTypes
, ale nie importujesz tego, musisz zaimportować PropTypes jako siebie lub użyćReact.PropTypes
react-router
zmianą interfejsu API w ciągu 5 minut .. haha żartuję, ale tylko częściowoOdpowiedzi:
Aby uzyskać prostą odpowiedź, możesz użyć
Link
komponentu fromreact-router
zamiastbutton
. Istnieją sposoby na zmianę trasy w JS, ale wydaje się, że nie potrzebujesz tego tutaj.<span className="input-group-btn"> <Link to="/login" />Click to login</Link> </span>
Aby zrobić to programowo w wersji 1.0.x, wykonaj następujące czynności wewnątrz funkcji clickHandler:
this.history.pushState(null, 'login');
Zaczerpnięte z dokumentu uaktualnienia tutaj
Do
this.history
komponentu obsługi trasy należało dodaćreact-router
. Jeśli jest to element potomnyroutes
niższy niż wymieniony w definicji, może być konieczne przekazanie go dalejźródło
if (true) { // redirect to login}
więc dlatego umieszczam to w onClick funkcja{validation && <Link to="/login" />Click to login</Link>}
. Jeśli walidacja jest fałszywa, nic się nie wyświetli.1) React-router> V5
useHistory
hook:Jeśli masz
React >= 16.8
i funkcjonalne komponenty, możesz użyćuseHistory
hooka z react-routera .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;
2) React-router> V4
withRouter
HOC:Jak @ambar wspomniał w komentarzach, React-router zmienił swoją bazę kodu od czasu wydania V4. Oto dokumentacja - oficjalna , z routerem
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);
3) React-router <V4 z
browserHistory
Możesz osiągnąć tę funkcjonalność za pomocą routera reaktywnego
BrowserHistory
. Kod poniżej:import React, { Component } from 'react'; import { browserHistory } from 'react-router'; export default class YourComponent extends Component { handleClick = () => { browserHistory.push('/login'); }; render() { return ( <div> <button onClick={this.handleClick} type="button"> </div> ); }; }
4) Redux
connected-react-router
Jeśli połączyłeś swój komponent z reduxem i skonfigurowałeś connect-respond -router , jedyne co musisz zrobić, to
this.props.history.push("/new/url");
to, że nie potrzebujeszwithRouter
HOC, aby wstrzyknąćhistory
do komponentu props.// 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 ( <div> <button onClick={this.handleClick} type="button"> </div> ); } }; } export default connect(mapStateToProps = {}, mapDispatchToProps = {})(YourComponent);
źródło
react-router-dom
robiNa przykład, gdy użytkownik kliknie łącze,
<Link to="/" />Click to route</Link>
zareaguje router, którego będzie szukał,/
a Ty możesz użyćRedirect to
i wysłać użytkownika w inne miejsce, na przykład trasę logowania.Z dokumentacji dla ReactRouterTraining :
import { Route, Redirect } from 'react-router' <Route exact path="/" render={() => ( loggedIn ? ( <Redirect to="/dashboard"/> ) : ( <PublicHomePage/> ) )}/>
<Redirect to="/somewhere/else"/>
<Redirect to={{ pathname: '/login', search: '?utm=your+face', state: { referrer: currentLocation } }}/>
źródło
<Redirect> elements are for router configuration only and should not be rendered
.Najłatwiej rozwiązanie dla sieci!
Do roku 2020
potwierdzono współpracę z:
"react-router-dom": "^5.1.2" "react": "^16.10.2"
Użyj
useHistory()
haka!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ódło
Z responsem-router v2.8.1 (prawdopodobnie także inne wersje 2.xx, ale nie testowałem tego) możesz użyć tej implementacji do przekierowania routera.
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'); } }
źródło
Najprostszym rozwiązaniem jest:
import { Redirect } from 'react-router'; <Redirect to='/componentURL' />
źródło