我能够通过使用来实现这一目标 bind() 。我想点击一个按钮 index.jsx ,将一些数据发布到服务器,评估响应,然后重定向到 success.jsx 。这就是我如何解决这个问题的方法......
bind()
index.jsx
success.jsx
index.jsx :
import React, { Component } from "react" import { postData } from "../../scripts/request" class Main extends Component { constructor(props) { super(props) this.handleClick = this.handleClick.bind(this) this.postData = postData.bind(this) } handleClick() { const data = { "first_name": "Test", "last_name": "Guy", "email": "test@test.com" } this.postData("person", data) } render() { return ( <div className="Main"> <button onClick={this.handleClick}>Test Post</button> </div> ) } } export default Main
request.js :
request.js
import { post } from "./fetch" export const postData = function(url, data) { // post is a fetch() in another script... post(url, data) .then((result) => { if (result.status === "ok") { this.props.history.push("/success") } }) }
success.jsx :
import React from "react" const Success = () => { return ( <div className="Success"> Hey cool, got it. </div> ) } export default Success
所以通过绑定 this 至 postData 在 index.jsx ,我能够访问 this.props.history 在 request.js ...然后我可以在不同的组件中重用此功能,只需要确保我记得包含 this.postData = postData.bind(this) 在里面 constructor() 。
this
postData
this.props.history
this.postData = postData.bind(this)
constructor()
我提供了一个解决方案,以防其他人有价值。
我有一个 history.js 文件我有以下内容:
history.js
import createHistory from 'history/createBrowserHistory' const history = createHistory() history.pushLater = (...args) => setImmediate(() => history.push(...args)) export default history
接下来,在我定义路由器的Root上,我使用以下内容:
import history from '../history' import { Provider } from 'react-redux' import { Router, Route, Switch } from 'react-router-dom' export default class Root extends React.Component { render() { return ( <Provider store={store}> <Router history={history}> <Switch> ... </Switch> </Router> </Provider> ) } }
最后,在我的 actions.js 我导入历史记录并使用pushLater
actions.js
import history from './history' export const login = createAction( ... history.pushLater({ pathname: PATH_REDIRECT_LOGIN }) ...)
这样,我可以在API调用后推送到新的操作。
希望能帮助到你!
React Router v4与v3(及更早版本)根本不同,你做不到 browserHistory.push() 就像你以前一样。
browserHistory.push()
这个讨论 如果你想要更多的信息似乎相关:
创建一个新的 browserHistory 不会工作,因为 <BrowserRouter> 创建自己的历史记录实例,并监听其中的更改。因此,不同的实例将更改URL但不更新 <BrowserRouter> 。 browserHistory 在v4中,反应路由器不会公开,仅在v2中。
browserHistory
<BrowserRouter>
相反,您有几个选项可以做到这一点:
withRouter
相反,你应该使用 withRouter 高阶组件,并将其包装到将推送到历史记录的组件。例如:
import React from "react"; import { withRouter } from "react-router-dom"; class MyComponent extends React.Component { ... myFunction() { this.props.history.push("/some/Path"); } ... } export default withRouter(MyComponent);
看看 的 官方文件 强> 了解更多信息:
你可以访问 history 对象的属性和最接近的 <Route> 的 match 通过withRouter高阶组件。 withRouter将在每次路径更改时使用相同的道具重新渲染其组件 <Route> 渲染道具: { match, location, history } 。
history
<Route>
match
{ match, location, history }
context
使用上下文可能是最简单的解决方案之一,但作为实验性API,它不稳定且不受支持。仅在其他一切都失败时使用它。这是一个例子:
import React from "react"; import PropTypes from "prop-types"; class MyComponent extends React.Component { static contextTypes = { router: PropTypes.object } constructor(props, context) { super(props, context); } ... myFunction() { this.context.router.history.push("/some/Path"); } ... }
看看吧 的 官方文件 强> 在上下文中:
如果您希望应用程序稳定,请不要使用上下文。它是一个实验性的API,很可能会在未来的React版本中破解。 如果您坚持使用上下文尽管存在这些警告,请尝试将上下文的使用隔离到一个小区域,并尽可能避免在可能的情况下直接使用上下文API,以便在API更改时更容易升级。
如果您希望应用程序稳定,请不要使用上下文。它是一个实验性的API,很可能会在未来的React版本中破解。
如果您坚持使用上下文尽管存在这些警告,请尝试将上下文的使用隔离到一个小区域,并尽可能避免在可能的情况下直接使用上下文API,以便在API更改时更容易升级。
讨厌的问题,花了我很多时间,但最终,我这样解决了:
包裹你的容器 withRouter 并将历史传递给您的行动 mapDispatchToProps 功能。在操作中使用history.push('/ url')进行导航。
mapDispatchToProps
行动:
export function saveData(history, data) { fetch.post('/save', data) .then((response) => { ... history.push('/url'); }) };
容器:
import { withRouter } from 'react-router-dom'; ... const mapDispatchToProps = (dispatch, ownProps) => { return { save: (data) => dispatch(saveData(ownProps.history, data))} }; export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Container));
这是有效的 的 React Router v4.x 强> 。
你可以像这样使用它来登录和manny不同的东西
class Login extends Component { constructor(props){ super(props); this.login=this.login.bind(this) } login(){ this.props.history.push('/dashboard'); } render() { return ( <div> <button onClick={this.login}>login</login> </div> )
React router V4现在允许使用历史支柱如下:
this.props.history.push("/dummy",value)
然后可以在位置道具可用的任何地方访问该值 state:{value} 不是组件状态。
state:{value}
我就这样做了:
import React, {Component} from 'react'; export default class Link extends Component { constructor(props) { super(props); this.onLogout = this.onLogout.bind(this); } onLogout() { this.props.history.push('/'); } render() { return ( <div> <h1>Your Links</h1> <button onClick={this.onLogout}>Logout</button> </div> ); } }
使用 this.props.history.push('/cart'); 要重定向到购物车页面,它将保存在历史记录对象中。
this.props.history.push('/cart');
享受,迈克尔。
第一步将您的应用程序包装在路由器
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的整个过程。
根据 React Router v4文档 - Redux Deep Integration会话
需要深度整合:
“能够通过调度行动导航”
但是,他们建议这种方法作为“深度整合”的替代方案:
“而不是分派行动进行导航,您可以将提供的历史记录对象传递给您的行为并在那里进行导航。”
因此,您可以使用withRouter高阶组件包装组件:
export default withRouter(connect(null, { actionCreatorName })(ReactComponent));
这会将历史API传递给道具。所以你可以调用动作创建者将历史作为参数传递。例如,在ReactComponent中:
onClick={() => { this.props.actionCreatorName( this.props.history, otherParams ); }}
然后,在你的actions / index.js里面:
export function actionCreatorName(history, param) { return dispatch => { dispatch({ type: SOME_ACTION, payload: param.data }); history.push("/path"); }; }
this.context.history.push 不管用。
this.context.history.push
我成功地推动了这样的工作:
static contextTypes = { router: PropTypes.object } handleSubmit(e) { e.preventDefault(); if (this.props.auth.success) { this.context.router.history.push("/some/Path") } }
在这种情况下,你将道具传递给你的thunk。所以你可以简单地打电话
props.history.push('/cart')
如果不是这种情况,您仍然可以从组件中传递历史记录
export function addProduct(data, history) { return dispatch => { axios.post('/url', data).then((response) => { dispatch({ type: types.AUTH_USER }) history.push('/cart') }) } }
/*Step 1*/ myFunction(){ this.props.history.push("/home"); } /**/ <button onClick={()=>this.myFunction()} className={'btn btn-primary'}>Go Home</button>
使用回调。它对我有用!
export function addProduct(props, callback) { return dispatch => axios.post(`${ROOT_URL}/cart`, props, config) .then(response => { dispatch({ type: types.AUTH_USER }); localStorage.setItem('token', response.data.token); callback(); }); }
在组件中,您只需添加回调
this.props.addProduct(props, () => this.props.history.push('/cart'))