Программно перемещаться с помощью реагирующего маршрутизатора
С react-router
я могу использовать элемент Link
для создания ссылок, которые обрабатываются обработчиком реакции вручную.
Я вижу внутри, он вызывает this.context.transitionTo(...)
.
Я хочу сделать навигацию, но не по ссылке, например, из раскрывающегося списка. Как это сделать в коде? Что такое this.context
?
Я видел микс Navigation
, но могу ли я сделать это без миксинов?
Ответы
Ответ 1
React Router v5.1.0 with hooks
В React Router> 5.1.0 есть новый хук useHistory
, если вы используете React> 16.8.0 и функциональные компоненты.
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
React Router v4
В версии 4 React Router существует три подхода к программной маршрутизации внутри компонентов.
- Используйте компонент высшего порядка
withRouter
.
- Используйте композицию и визуализируйте
<Route>
- Используйте
context
.
React Router - это в основном оболочка для библиотеки history
. history
обрабатывает взаимодействие с браузером window.history
для вас с его браузером и историей хэширования. Он также предоставляет историю памяти, которая полезна для сред, в которых нет глобальной истории. Это особенно полезно при разработке мобильных приложений (react-native
) и модульном тестировании с Node.
Экземпляр history
имеет два метода навигации: push
и replace
. Если вы рассматриваете history
как массив посещенных местоположений, push
добавит новое местоположение в массив, а replace
заменит текущее местоположение в массиве новым. Обычно вы хотите использовать метод push
при навигации.
В более ранних версиях React Router вам приходилось создавать собственный экземпляр history
, но в версии 4 компоненты <BrowserRouter>
, <HashRouter>
и <MemoryRouter>
будут создавать для вас экземпляры браузера, хеш-функции и памяти. React Router делает свойства и методы экземпляра history
, связанного с вашим маршрутизатором, доступными через контекст в объекте router
.
1. Используйте withRouter
компонент высшего порядка
Компонент высшего порядка withRouter
будет вводить объект history
как опору компонента. Это позволяет вам получить доступ к методам push
и replace
без необходимости иметь дело с context
.
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
2. Используйте композицию и визуализируйте <Route>
Компонент <Route>
предназначен не только для сопоставления местоположений. Вы можете отобразить маршрут без пути, и он всегда будет соответствовать текущему местоположению. Компонент <Route>
проходит те же реквизиты, что и withRouter
, поэтому вы сможете получить доступ к методам history
через реквизит history
.
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
3. Используйте контекст *
Но вы, вероятно, не должны
Последний вариант - тот, который вам следует использовать, только если вы чувствуете себя комфортно при работе с моделью Rea context. Хотя контекст является опцией, следует подчеркнуть, что контекст - это нестабильный API, и в документации React есть раздел Почему бы не использовать контекст. Так что используйте на свой страх и риск!
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1 и 2 - самый простой вариант реализации, поэтому в большинстве случаев они являются вашими лучшими ставками.
Ответ 2
React-Router 5.1.0+ Answer (using hooks и React >16.8)
Вы можете использовать новый хук useHistory
для функциональных компонентов и программно перемещаться:
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React-Router 4.0.0+ Answer
В версии 4.0 и выше используйте историю как опору вашего компонента.
class Example extends React.Component {
// use 'this.props.history.push('/some/path')' here
};
ПРИМЕЧАНИЕ: this.props.history не существует в том случае, если ваш компонент не был обработан <Route>
. Вы должны использовать <Route path="..." component={YourComponent}/>
, чтобы иметь this.props.history в YourComponent
React-Router 3.0.0+ Answer
В версии 3.0 и выше используйте маршрутизатор в качестве опоры для вашего компонента.
class Example extends React.Component {
// use 'this.props.router.push('/some/path')' here
};
React-Router 2.4.0+ Answer
В версии 2.4 и выше используйте компонент более высокого порядка, чтобы маршрутизатор стал опорой для вашего компонента.
import { withRouter } from 'react-router';
class Example extends React.Component {
// use 'this.props.router.push('/some/path')' here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React-Router 2.0.0+ Answer
Эта версия обратно совместима с 1.x, поэтому нет необходимости в Руководстве по обновлению. Достаточно просто пройтись по примерам.
Тем не менее, если вы хотите переключиться на новый шаблон, внутри маршрутизатора есть модуль browserHistory, к которому вы можете получить доступ с помощью
import { browserHistory } from 'react-router'
Теперь у вас есть доступ к истории браузера, поэтому вы можете выполнять такие операции, как push, replace и т.д. Например:
browserHistory.push('/some/path')
Дальнейшее чтение:
Истории и
навигации
React-Router 1.x.x Answer
Я не буду вдаваться в детали обновления. Вы можете прочитать об этом в Руководстве по обновлению
.Основное изменение в этом вопросе - это переход от Mixin навигации к истории. Теперь он использует браузер historyAPI для изменения маршрута, поэтому теперь мы будем использовать pushState()
.
Вот пример использования Mixin:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, '/help');
}
})
Обратите внимание, что этот History
происходит из проекта rackt/history. Не от самого React-Router.
Если вы не хотите использовать Mixin по какой-либо причине (возможно, из-за класса ES6), то вы можете получить доступ к истории, полученной от маршрутизатора из this.props.history
. Он будет доступен только для компонентов, предоставляемых вашим маршрутизатором. Поэтому, если вы хотите использовать его в любых дочерних компонентах, его нужно передать как атрибут через props
.
Вы можете прочитать больше о новой версии в их документации 1.0.x
Вот страница справки, посвященная навигации за пределами вашего компонента
Он рекомендует получить ссылку history = createHistory()
и вызвать replaceState
для этого.
React-Router 0.13.x Answer
Я попал в ту же проблему и смог найти решение только с помощью навигационного миксина, поставляемого с реагирующим маршрутизатором.
Вот как я это сделал
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
Мне удалось позвонить transitionTo()
без необходимости доступа к .context
Или вы можете попробовать фантастический ES6 class
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React-Router-Redux
Примечание. Если вы используете Redux, существует еще один проект под названием React-Router-Redux, который дает вам редукционные привязки для ReactRouter, используя несколько такой же подход, как React-Redux делает
React-Router-Redux имеет несколько доступных методов, которые позволяют легко перемещаться изнутри создателей действий. Они могут быть особенно полезны для людей, которые имеют существующую архитектуру в React Native, и они хотят использовать те же шаблоны в React Web с минимальными дополнительными затратами.
Изучите следующие методы:
push(location)
replace(location)
go(number)
goBack()
goForward()
Вот пример использования с Redux-Thunk:
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
Ответ 3
React-Router v2
Для самой последней версии (v2.0.0-rc5
) рекомендуемый метод навигации заключается в прямом нажатии на одноэлементную историю. Это можно увидеть в действии в документе " Навигация за пределами компонентов".
Соответствующая выдержка:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
Если вы используете более новый API реагирующего маршрутизатора, вам нужно использовать history
из this.props
когда внутри компонентов так:
this.props.history.push('/some/path');
Он также предлагает pushState
но это устарело для зарегистрированных предупреждений.
При использовании react-router-redux
он предлагает функцию push
вы можете отправить следующим образом:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
Однако это может использоваться только для изменения URL, а не для перехода на страницу.
Ответ 4
Вот как вы делаете это с react-router v2.0.0
с ES6. react-router
отошел от миксинов.
import React from 'react';
export default class MyComponent extends React.Component {
navigateToPage = () => {
this.context.router.push('/my-route')
};
render() {
return (
<button onClick={this.navigateToPage}>Go!</button>
);
}
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
}
Ответ 5
React-Router 4.x Ответ:
С моей стороны, мне нравится иметь единственный объект истории, который я могу нести даже за пределами компонентов. Мне нравится иметь один файл history.js, который я импортирую по требованию, и просто манипулировать им.
Вам просто нужно изменить BrowserRouter
на Router и указать реквизиты истории. Это ничего не меняет для вас, за исключением того, что у вас есть свой собственный объект истории, которым вы можете манипулировать, как хотите.
Вам нужно установить историю, библиотеку, которую использует react-router
.
Пример использования, обозначение ES6:
history.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
BasicComponent.js
import React, { Component } from 'react';
import history from './history';
class BasicComponent extends Component {
goToIndex(e){
e.preventDefault();
history.push('/');
}
render(){
return <a href="#" onClick={this.goToIndex}>Previous</a>;
}
}
РЕДАКТИРОВАТЬ 16 апреля 2018 года:
Если вам нужно перейти от компонента, который фактически отображается из компонента Route
, вы также можете получить доступ к истории из реквизита, например:
BasicComponent.js
import React, { Component } from 'react';
class BasicComponent extends Component {
navigate(e){
e.preventDefault();
this.props.history.push('/url');
}
render(){
return <a href="#" onClick={this.navigate}>Previous</a>;
}
}
Ответ 6
Для этого, кто не контролирует серверную часть и из-за этого использует hash router v2:
Поместите свою историю в отдельный файл (например, app_history.js ES6):
import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
export default appHistory;
И используйте это везде!
Ваша точка входа для реагирующего маршрутизатора (app.js ES6):
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
<Router history={appHistory}>
...
</Router>
), document.querySelector('[data-role="app"]'));
Ваша навигация внутри любого компонента (ES6):
import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
if (err) {
console.error(err); // login failed
} else {
// logged in
appHistory.replace('/dashboard'); // or .push() if you don't need .replace()
}
})
Ответ 7
React Router V4
ТЛ: д-р;
if (navigate) {
return <Redirect to="/" push={true} />
}
Простой и декларативный ответ заключается в том, что вам нужно использовать <Redirect to={URL} push={boolean}/>
в сочетании с setState()
push: boolean - при значении true перенаправление будет помещать новую запись в историю вместо замены текущей.
import { Redirect } from 'react-router'
class FooBar extends React.Component {
state = {
navigate: false
}
render() {
const { navigate } = this.state
// here is the important part
if (navigate) {
return <Redirect to="/" push={true} />
}
// ^^^^^^^^^^^^^^^^^^^^^^^
return (
<div>
<button onClick={() => this.setState({ navigate: true })}>
Home
</button>
</div>
)
}
}
Полный пример здесь. Узнайте больше здесь.
PS. В примере используются инициализаторы свойств ES7+ для инициализации состояния. Посмотри здесь, если тебе интересно.
Ответ 8
Предупреждение: этот ответ охватывает только версии ReactRouter до 1.0
Я обновлю этот ответ вариантами использования 1.0.0-rc1 после!
Вы можете сделать это и без миксинов.
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
Причиной с контекстами является то, что он недоступен, если вы не определите contextTypes
для класса.
Что касается контекста, то это объект, подобный реквизиту, который передается от родителя к потомку, но он передается неявно, без необходимости каждый раз переопределять реквизиты. См. Https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html.
Ответ 9
Я попробовал по крайней мере 10 способов сделать это, прежде чем что-то заработало!
@Felipe Skinner withRouter
ответил мне немного ошеломляюще, и я не был уверен, что хочу делать новые имена классов "ExportedWithRouter".
Вот самый простой и понятный способ сделать это, в настоящее время React-Router 3.0.0 и ES6:
React-Router 3.xx с ES6:
import { withRouter } from 'react-router';
class Example extends React.Component {
// use 'this.props.router.push('/some/path')' here
};
// Export the decorated class
export default withRouter(Example);
или, если это не ваш класс по умолчанию, экспортируйте как:
withRouter(Example);
export { Example };
Обратите внимание, что в 3.xx сам компонент <Link>
использует router.push
, поэтому вы можете передавать его как угодно, передавая <Link to=
, например:
this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
Ответ 10
Чтобы выполнить навигацию программно, вам нужно добавить новую историю в props.history в вашем component
, чтобы что-то вроде этого могло сделать работу за вас:
//using ES6
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick(e) {
e.preventDefault()
/* Look at here, you can add it here */
this.props.history.push('/redirected');
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Redirect!!!
</button>
</div>
)
}
}
export default App;
Ответ 11
Для компонентов ES6 + React у меня сработало следующее решение.
Я последовал за Фелиппом Скиннером, но добавил комплексное решение, чтобы помочь таким начинающим, как я.
Ниже приведены версии, которые я использовал:
"response-router": "^ 2.7.0"
"реагировать": "^ 15.3.1"
Ниже приведен мой компонент реакции, где я использовал программную навигацию с использованием реагирующего маршрутизатора:
import React from 'react';
class loginComp extends React.Component {
constructor( context) {
super(context);
this.state = {
uname: '',
pwd: ''
};
}
redirectToMainPage(){
this.context.router.replace('/home');
}
render(){
return <div>
// skipping html code
<button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
</div>;
}
};
loginComp.contextTypes = {
router: React.PropTypes.object.isRequired
}
module.exports = loginComp;
Ниже приведена конфигурация для моего маршрутизатора:
import { Router, Route, IndexRedirect, browserHistory } from 'react-router'
render(<Router history={browserHistory}>
<Route path='/' component={ParentComp}>
<IndexRedirect to = "/login"/>
<Route path='/login' component={LoginComp}/>
<Route path='/home' component={HomeComp}/>
<Route path='/repair' component={RepairJobComp} />
<Route path='/service' component={ServiceJobComp} />
</Route>
</Router>, document.getElementById('root'));
Ответ 12
Возможно, это не лучший подход, но... С помощью response-router v4 следующий Typescript может дать представление для некоторых.
В представленном компоненте ниже, например, LoginPage
, объект router
доступен и просто вызовите router.transitionTo('/homepage')
для навигации.
Код навигации был взят из.
"react-router": "^4.0.0-2",
"react": "^15.3.1",
import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
interface MatchWithPropsInterface {
component: typeof React.Component,
router: Router,
history: History,
exactly?: any,
pattern: string
}
class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
render() {
return(
<Match {...this.props} render={(matchProps) => (
React.createElement(this.props.component, this.props)
)}
/>
)
}
}
ReactDOM.render(
<Router>
{({ router }) => (
<div>
<MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
<Miss component={NotFoundView} />
</div>
)}
</Router>,
document.getElementById('app')
);
Ответ 13
Ниже приведен рабочий код: Как уже говорилось в этой статье, это очень простой способ навигации с использованием реагирующего маршрутизатора:
class Register extends React.Component {
state = {
toDashboard: false,
}
handleSubmit = (user) => {
saveUser(user)
.then(() => this.setState(() => ({
toDashboard: true
})))
}
render() {
if (this.state.toDashboard === true) {
return <Redirect to='/dashboard' />
}
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
< Redirect/> есть
Композитный ✅ Декларативный ✅ Пользовательское событие → Изменение состояния → Повторная визуализация ✅
Компонент Register обрабатывается React Router, наш код может выглядеть следующим образом
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
добавив withRouter, это будет выглядеть так
import {
withRouter
} from 'react-router-dom'
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
export default withRouter(Register)
Существует два способа программной навигации с помощью React Router - и history.push. То, что вы используете, в основном зависит от вас и вашего конкретного случая использования, хотя я стараюсь отдавать предпочтение Redirect.
Ответ 14
В React-Router v4 и ES6
Вы можете использовать withRouter
и this.props.history.push
.
import {withRouter} from 'react-router-dom';
class Home extends Component {
componentDidMount() {
this.props.history.push('/redirect-to');
}
}
export default withRouter(Home);
Ответ 15
Чтобы использовать withRouter
с компонентом на основе классов, попробуйте что-то вроде этого ниже. Не забудьте изменить оператор экспорта для использования withRouter
:
import { withRouter } from 'react-router-dom'
class YourClass extends React.Component {
yourFunction = () => {
doSomeAsyncAction(() =>
this.props.history.push('/other_location')
)
}
render() {
return (
<div>
<Form onSubmit={ this.yourFunction } />
</div>
)
}
}
export default withRouter(YourClass);
Ответ 16
с React-Router v4 на горизонте, теперь есть новый способ сделать это.
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
response-lego - это пример приложения, которое показывает как использовать/обновлять реагировать-маршрутизатор, и содержит примеры функциональных тестов, которые перемещаются по приложению.
Ответ 17
основываясь на предыдущем ответе
от Хосе Антонио Постиго и Бена Уилера
новинка? должен быть написан в Typescript
и использование декораторов
ИЛИ статическое свойство/поле
import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";
export interface INavigatorProps {
router?: ReactRouter.History.History;
}
/**
* Note: goes great with mobx
* @inject("something") @withRouter @observer
*/
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
navigate: (to: string) => void;
constructor(props: INavigatorProps) {
super(props);
let self = this;
this.navigate = (to) => self.props.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
/**
* Non decorated
*/
export class Navigator2 extends Component<INavigatorProps, {}> {
static contextTypes = {
router: React.PropTypes.object.isRequired,
};
navigate: (to: string) => void;
constructor(props: INavigatorProps, context: any) {
super(props, context);
let s = this;
this.navigate = (to) =>
s.context.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
с любым установленным сегодня npm. "response-router": "^ 3.0.0" и
"@types/реакции-маршрутизатор": "^ 2.0.41"
Ответ 18
В реакции роутера v4. Я следую этому двухстороннему маршруту программно.
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
Номер два
Заменяет текущую запись в стеке истории
Чтобы получить историю в реквизитах, вам, возможно, придется обернуть свой компонент с помощью
withRouter
Ответ 19
Если вы используете хеш или историю браузера, вы можете сделать
hashHistory.push('/login');
browserHistory.push('/login');
Ответ 20
В текущей версии React (15.3) this.props.history.push('/location');
работал для меня, но он показал следующее предупреждение:
browser.js: 49 Предупреждение: [ props.history
-router] props.history
и context.history
устарели. Пожалуйста, используйте context.router
.
и я решил это с помощью context.router
следующим образом:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.backPressed = this.backPressed.bind(this);
}
backPressed() {
this.context.router.push('/back-location');
}
...
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
export default MyComponent;
Ответ 21
React-Router V4
если вы используете версию 4, то вы можете использовать мою библиотеку (плагин Shameless), где вы просто отправляете действие, и все просто работает!
dispatch(navigateTo("/aboutUs"));
trippler
Ответ 22
Те, кто сталкивается с проблемами в реализации этого на реакции-маршрутизатор v4.
Вот рабочее решение для навигации по приложению реагировать на редукционные действия.
history.js
import createHistory from 'history/createBrowserHistory'
export default createHistory()
App.js/Route.jsx
import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
<Route path="/test" component={Test}/>
</Router>
another_file.js ИЛИ редукционный файл
import history from './history'
history.push('/test') // this should change the url and re-render Test component
Все благодаря этому комментарию: ReactTraining выпускает комментарий
Ответ 23
Если случится с парой RR4 с редуктом через response -router-redux, используйте создатели действий маршрутизации из react-router-redux
.
import { push, replace, ... } from 'react-router-redux'
class WrappedComponent extends React.Component {
handleRedirect(url, replaceState = true) {
replaceState
? this.props.dispatch(replace(url))
: this.props.dispatch(push(url))
}
render() { ... }
}
export default connect(null)(WrappedComponent)
Если для управления асинхронным потоком используется redux thunk/saga, лучше импортируйте создателей вышеуказанных действий в действиях redux и подключайте для реагирования компоненты, используя mapDispatchToProps.
Ответ 24
Возможно, не лучшее решение, но оно выполняет свою работу:
import { Link } from 'react-router-dom';
// create functional component Post
export default Post = () => (
<div className="component post">
<button className="button delete-post" onClick={() => {
// ... delete post
// then redirect, without page reload, by triggering a hidden Link
document.querySelector('.trigger.go-home').click();
}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>
);
По сути, логика, связанная с одним действием (в данном случае удаление сообщения), в итоге вызовет триггер для перенаправления. Это не идеально, потому что вы добавите триггер DOM-узла к вашей разметке, чтобы вы могли удобно вызывать его при необходимости. Кроме того, вы будете напрямую взаимодействовать с DOM, что в компоненте React может быть нежелательно.
Тем не менее, этот тип перенаправления не требуется так часто. Таким образом, одна или две дополнительные скрытые ссылки в разметке вашего компонента не повредят так сильно, особенно если вы дадите им значимые имена.
Ответ 25
Правильный ответ был для меня на момент написания
this.context.router.history.push('/');
Но вам нужно добавить PropTypes в ваш компонент
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
Не забудьте импортировать PropTypes
import PropTypes from 'prop-types';
Ответ 26
Вы также можете использовать ловушку useHistory
в компоненте без состояния. Пример из документации.
import { useHistory } from "react-router"
function HomeButton() {
const history = useHistory()
return (
<button type="button" onClick={() => history.push("/home")}>
Go home
</button>
)
}
Note: Hooks were added in [email protected]
и require [email protected]>=16.8
Ответ 27
Это сработало для меня, нет необходимости в специальном импорте:
<input
type="button"
name="back"
id="back"
class="btn btn-primary"
value="Back"
onClick={() => { this.props.history.goBack() }}
/>
Ответ 28
Для React Router v4+
Предполагая, что вам не нужно будет перемещаться во время самого начального рендеринга (для которого вы можете использовать компонент <Redirect>
), это то, что мы делаем в нашем приложении.
Определите пустой маршрут, который возвращает ноль, это позволит вам получить доступ к объекту истории. Вы должны сделать это на верхнем уровне, где определен ваш Router
.
Теперь вы можете делать все, что можно сделать в истории, например history.push()
, history.replace()
, history.go(-1)
т.д.!
import React from 'react';
import { HashRouter, Route } from 'react-router-dom';
let routeHistory = null;
export function navigateTo(path) {
if(routeHistory !== null) {
routeHistory.push(path);
}
}
export default function App(props) {
return (
<HashRouter hashType="noslash">
<Route
render={({ history }) => {
routeHistory = history;
return null;
}}
/>
{/* Rest of the App */}
</HashRouter>
);
}
Ответ 29
Вы можете использовать этот метод другим компонентом.
toProfile() {
this.context.history.pushState(null, 'profile');
}
и добавьте функцию onClick
<li onClick={this.toProfile.bind(this)></li>
надеюсь, что это полезно для вас.
Ответ 30
В зависимости от , где вы хотите перенаправить. Если внутри компонента, то ответ @Paul S - лучший способ сделать это.
Но если вы хотите перенаправить из любого места внутри приложения, я рекомендую использовать react-router-redux