在当前版本的React Router (v3)中,我可以接受服务器响应并使用browserHistory。点击进入相应的响应页面。但是,这在v4中是不可用的,我不确定处理它的适当方法是什么。
在这个例子中,使用Redux, components/app-product-form.js在用户提交表单时调用this.props. addproduct (props)。当服务器返回成功时,用户将被带到Cart页面。
// actions/index.js
export function addProduct(props) {
return dispatch =>
axios.post(`${ROOT_URL}/cart`, props, config)
.then(response => {
dispatch({ type: types.AUTH_USER });
localStorage.setItem('token', response.data.token);
browserHistory.push('/cart'); // no longer in React Router V4
});
}
如何从React Router v4的函数重定向到购物车页面?
这是我的hack(这是我的根级文件,其中混合了一些redux -尽管我没有使用react-router-redux):
const store = configureStore()
const customHistory = createBrowserHistory({
basename: config.urlBasename || ''
})
ReactDOM.render(
<Provider store={store}>
<Router history={customHistory}>
<Route component={({history}) => {
window.appHistory = history
return (
<App />
)
}}/>
</Router>
</Provider>,
document.getElementById('root')
)
然后,我可以在任何我想要的地方使用window.appHistory.push()(例如,在我的redux商店函数/ thacks /sagas等),我希望我可以只使用window.customHistory.push(),但出于某种原因,react-router似乎从未更新,即使url发生了变化。但是这样我就有了react-router使用的EXACT实例。我不喜欢把东西放在全球范围内,这是我做过的为数不多的事情之一。但在我看来,这比我见过的任何其他选择都要好。
如果你正在使用Redux,那么我建议使用npm包react-router-redux。它允许您分派Redux存储导航操作。
你必须在他们的自述文件中创建存储。
最简单的用例:
import { push } from 'react-router-redux'
this.props.dispatch(push('/second page'));
容器/组件的第二个用例:
容器:
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import Form from '../components/Form';
const mapDispatchToProps = dispatch => ({
changeUrl: url => dispatch(push(url)),
});
export default connect(null, mapDispatchToProps)(Form);
组件:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class Form extends Component {
handleClick = () => {
this.props.changeUrl('/secondPage');
};
render() {
return (
<div>
<button onClick={this.handleClick}/>
</div>Readme file
);
}
}
第一步在路由器中包装你的应用程序
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(<Router><App /></Router>, document.getElementById('root'));
现在我的整个应用程序都可以访问BrowserRouter。第二步,我导入Route,然后传递这些道具。可能在你的一个主文件里。
import { Route } from "react-router-dom";
//lots of code here
//somewhere in my render function
<Route
exact
path="/" //put what your file path is here
render={props => (
<div>
<NameOfComponent
{...props} //this will pass down your match, history, location objects
/>
</div>
)}
/>
现在如果我在我的组件js文件中运行console.log(this.props),我应该得到类似这样的东西
{match: {…}, location: {…}, history: {…}, //other stuff }
步骤2访问历史记录对象,修改位置
//lots of code here relating to my whatever request I just ran delete, put so on
this.props.history.push("/") // then put in whatever url you want to go to
另外,我只是一个编程训练营的学生,所以我不是专家,但我知道你也可以使用
window.location = "/" //wherever you want to go
如果我错了,请纠正我,但当我测试出来的时候,它重新加载了整个页面,我认为这击败了使用React的整个意义。
您可以在组件外部使用历史方法。试试下面的方法。
首先,使用历史包创建一个历史对象:
// src/history.js
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
然后将它包装在<Router>中(请注意,你应该使用import {Router}而不是import {BrowserRouter as Router}):
// src/index.jsx
// ...
import { Router, Route, Link } from 'react-router-dom';
import history from './history';
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/login">Login</Link></li>
</ul>
<Route exact path="/" component={HomePage} />
<Route path="/login" component={LoginPage} />
</div>
</Router>
</Provider>,
document.getElementById('root'),
);
从任何地方更改当前位置,例如:
// src/actions/userActionCreators.js
// ...
import history from '../history';
export function login(credentials) {
return function (dispatch) {
return loginRemotely(credentials)
.then((response) => {
// ...
history.push('/');
});
};
}
UPD:你也可以在React Router FAQ中看到一个稍微不同的例子。