Как сделать перенаправление на другой маршрут с помощью ретранслятора?
Я пытаюсь сделать ПРОСТОЙ с использованием реакции-маршрутизатора (версия ^ 1.0.3), чтобы перенаправить на другое представление, и я просто устаю.
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;
все, что мне нужно, это отправить использование '/login' и все.
Что я могу сделать?
ошибки в консоли:
Uncaught ReferenceError: PropTypes не определен
файл с моими маршрутами
// 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>
);
Ответы
Ответ 1
Для простого ответа вы можете использовать Link
компонент из react-router
вместо button
. Есть способы изменить маршрут в JS, но, похоже, вам здесь это не нужно.
<span className="input-group-btn">
<Link to="/login" />Click to login</Link>
</span>
Чтобы сделать это программно в 1.0.x, вы сделаете это так, внутри вашей функции clickHandler:
this.history.pushState(null, 'login');
Взято из обновления doc здесь
У вас должен быть this.history
размещен на вашем компоненте обработчика маршрута на react-router
. Если это дочерний компонент ниже указанного в routes
определении, вам может потребоваться пройти, что дальше далее
Ответ 2
1) реакции-роутер> V4 можно использовать с withRouter
HOC:
Как упомянул в комментариях @ambar, React-router изменил свою кодовую базу с момента выпуска V4. Вот документация - официальная, с рутером
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-роутер <V4
Вы можете достичь этой функциональности с помощью реакции-маршрутизатора BrowserHistory
. Код ниже:
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) С резервным connected-react-router
Если вы подключили свой компонент с помощью redux и настроили подключенный-реагирующий-маршрутизатор, все, что вам нужно сделать, это this.props.history.push("/new/url");
то есть вам не нужен withRouter
HOC для withRouter
history
в реквизиты компонента.
// 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);
Ответ 3
Как сделать перенаправление на другой маршрут с помощью ретранслятора?
Например, когда пользователь нажимает ссылку <Link to="/" />Click to route</Link>
, реакция-маршрутизатор будет искать /
, и вы можете использовать Redirect to
и отправлять пользователя в другое место, как маршрут входа.
Из docs для ReactRouterTraining:
Рендеринг <Redirect>
будет перемещаться в новое место. Новый местоположение переопределит текущее местоположение в стеке истории, например серверные переадресации (HTTP 3xx).
import { Route, Redirect } from 'react-router'
<Route exact path="/" render={() => (
loggedIn ? (
<Redirect to="/dashboard"/>
) : (
<PublicHomePage/>
)
)}/>
to: string, URL для перенаправления.
<Redirect to="/somewhere/else"/>
to: object, местоположение для перенаправления.
<Redirect to={{
pathname: '/login',
search: '?utm=your+face',
state: { referrer: currentLocation }
}}/>
Ответ 4
С реакционным маршрутизатором v2.8.1 (возможно, и с другими версиями 2.x.x, но я его не тестировал) вы можете использовать эту реализацию для перенаправления маршрутизатора.
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
Самое простое решение:
import { Redirect } from 'react-router';
<Redirect to='/componentURL' />