С react-router
я могу использовать элемент Link
для создания ссылок, которые обрабатываются обработчиком реакции вручную.
Я вижу внутри, он вызывает this.context.transitionTo(...)
.
Я хочу сделать навигацию, но не по ссылке, например, из раскрывающегося списка. Как это сделать в коде? Что такое this.context
?
Я видел микс Navigation
, но могу ли я сделать это без миксинов?
React Router v4
В версии 4 React Router существует три подхода к программной маршрутизации внутри компонентов.
withRouter
высшего порядка withRouter
.<Route>
context
. React Router - это в основном оболочка для библиотеки history
. history
обрабатывает взаимодействие с браузером window.history
для вас с его браузером и хэш-историями. Он также предоставляет историю памяти, которая полезна для сред, в которых нет глобальной истории. Это особенно полезно при разработке мобильных приложений (react-native
) и модульном тестировании с Node
Экземпляр history
имеет два метода навигации: push
и replace
. Если вы воспринимаете history
как массив посещенных местоположений, push
добавит новое местоположение в массив, а replace
заменит текущее местоположение в массиве новым. Обычно вы хотите использовать метод push
во время навигации.
В более ранних версиях React Router вам приходилось создавать собственный экземпляр history
, но в v4 <BrowserRouter>
, <HashRouter>
и <MemoryRouter>
будут создавать для вас экземпляры браузера, хеш-функции и памяти. React Router делает свойства и методы экземпляра history
связанного с вашим маршрутизатором, доступными через контекст под объектом router
.
withRouter
высшего порядка withRouter
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>
))
<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>
)} />
)
Но вы, вероятно, не должны
Последний вариант - тот, который вам следует использовать, только если вам комфортно работать с контекстной моделью React. Несмотря на то, что контекст является опцией, следует подчеркнуть, что контекст является нестабильным 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 - самый простой вариант реализации, поэтому для большинства случаев использования они являются вашими лучшими ставками.
<Redirect>
.
React-Router 4.0. 0+ Ответ
В 4.0 и выше используйте историю как опору вашего компонента.
class Example extends React.Component {
// use 'this.props.history.push('/some/path')' here
};
React-Router 3.0. 0+ Ответ
В версии 3.0 и выше используйте маршрутизатор в качестве опоры для вашего компонента.
class Example extends React.Component {
// use 'this.props.router.push('/some/path')' here
};
React-Router 2.4. 0+ Ответ
В версии 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+ Ответ
Эта версия обратно совместима с 1.x, поэтому нет необходимости в Руководстве по обновлению. Просто пройтись по примерам должно быть достаточно хорошо.
Тем не менее, если вы хотите переключиться на новый шаблон, внутри маршрутизатора есть модуль browserHistory, к которому вы можете получить доступ.
import { browserHistory } from 'react-router'
Теперь у вас есть доступ к истории браузера, поэтому вы можете выполнять такие операции, как push, replace и т.д.
browserHistory.push('/some/path')
Дальнейшее чтение: истории и навигация
React-Router 1.xx Ответ
Я не буду вдаваться в детали обновления. Вы можете прочитать об этом в Руководстве по обновлению.
Основное изменение в этом вопросе - это переход от миксина навигации к истории. Теперь он использует браузер 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 Ответ
Я попал в ту же проблему и смог найти решение только с помощью навигационного миксина, который поставляется с реагирующим маршрутизатором.
Вот как я это сделал
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
Или вы можете попробовать модный class
ES6
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
};
Реагировать-маршрутизатор-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>
Navigation.transitionTo
, вы очень часто звоните .context
.
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, а не для перехода на страницу.
import { browserHistory } from './react-router'
но вместо этого создает историю, используя import createBrowserHistory from 'history/lib/createBrowserHistory'
. Позже вы можете получить доступ к history
из реквизита компонентов: this.props.history('/some/path')
Вот как вы делаете это с 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
}
history
как заявлено @Bobby. Вы можете использовать context.router
но вы действительно затрудняете модульное тестирование этих компонентов, поскольку создание экземпляра только того компонента не будет иметь этого в контексте.
Для этого, кто не контролирует серверную часть и из-за этого использует 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()
}
})
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>;
}
}
Router
вместо BrowserRouter
. BrowserRouter
создает и поддерживает объект history
для вас. Вы не должны по умолчанию создавать свои собственные, только если вам ["нужна глубокая интеграция с инструментами управления состоянием, такими как Redux." ) Acttraining.com/react-router/web/api/Router
this.props.history
по умолчанию, я пока не нашел решения, которое могло бы помочь мне сделать такую вещь в классе, который не является компонентом, или любой другой инструмент, который не построен как компонент React, к которому вы можете передавать реквизит. Спасибо за ваш отзыв :)
Предупреждение: этот ответ охватывает только версии 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.
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+ для инициализации состояния. Посмотри здесь, если тебе интересно.
withRouter
не работало, когда уже на маршруте, который перезагружается. В нашем случае нам пришлось либо выборочно выполнить setState
(вызывая return <Redirect>
), если он уже есть на маршруте, либо history.push()
из другого места.
Я попробовал по крайней мере 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'})'
200 OK
вместо 30x
кода. Как я могу исправить эту проблему?
Чтобы выполнить навигацию программно, вам нужно добавить новую историю в 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;
Для компонентов 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'));
Может быть, не лучший подход, но... Используя response-router v4, следующий Typescript может дать представление для некоторых.
В представленном компоненте ниже, например. Объект LoginPage
, router
доступен и просто вызывает router.transitionTo('/homepage')
для навигации.
Код навигации был взят из https://react-router.now.sh/Match.
"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')
);
В 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);
Чтобы использовать 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);
Ниже приведен рабочий код: Как уже говорилось в этой статье, это очень простой способ навигации с использованием реагирующего маршрутизатора:
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.
основываясь на предыдущем ответе
от Хосе Антонио Постиго и Бена Уилера
новинка? должен быть написан в 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"
с 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 - это пример приложения, которое показывает, как использовать/обновлять реактив-маршрутизатор, и включает примеры функциональных тестов, которые перемещаются по приложению.
В реакции роутера v4. Я следую этому двухстороннему маршруту программно.
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
Номер два
Заменяет текущую запись в стеке истории
Чтобы получить историю в реквизитах, вам, возможно, придется обернуть свой компонент с
withRouter https://reacttraining.com/react-router/core/api/withRouter
Если вы используете хеш или историю браузера, вы можете сделать
hashHistory.push('/login');
browserHistory.push('/login');
hashHistory.push
, дает Cannot прочитать свойство "push" из неопределенного. Откуда вы их импортируете?
В текущей версии 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;
React-Router V4
если вы используете версию 4, тогда вы можете использовать мою библиотеку (Shameless plug), где вы просто отправляете действие, и все просто работает!
dispatch(navigateTo("/aboutUs"));
Если случится с парой 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.
react-router-redux
давно устарел / заархивирован
Правильный ответ был для меня на момент написания
this.context.router.history.push('/');
Но вам нужно добавить PropTypes в ваш компонент
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
Не забудьте импортировать PropTypes
import PropTypes from 'prop-types';
Возможно, не лучшее решение, но оно выполняет свою работу:
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 может быть нежелательно.
Тем не менее, этот тип перенаправления не требуется так часто. Таким образом, одна или две дополнительные скрытые ссылки в разметке вашего компонента не повредят так сильно, особенно если вы дадите им значимые имена.
Те, кто сталкивается с проблемами в реализации этого на реакции-маршрутизатор 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
Все благодаря этому комментарию: https://github.com/ReactTraining/react-router/issues/3498#issuecomment-301057248
В зависимости от , где вы хотите перенаправить. Если внутри компонента, то ответ @Paul S - лучший способ сделать это.
Но если вы хотите перенаправить из любого места внутри приложения, я рекомендую использовать react-router-redux
Вы можете использовать этот метод другим компонентом.
toProfile() {
this.context.history.pushState(null, 'profile');
}
и добавьте функцию onClick
<li onClick={this.toProfile.bind(this)></li>
надеюсь, что это полезно для вас.
Просто используйте this.props.history.push('/where/to/go');
Вы можете использовать
document.location.hash = 'path'
Примечания: