如何在ReactRouterv4中推送到History

在当前版本的 React Router(v3)中,我可以接受服务器响应并使用browserHistory.push转到相应的响应页面。但是,这在 v4 中不可用,我不确定处理此问题的适当方法是什么。

在当前版本的 React Router(v3)中,我可以接受服务器响应并使用browserHistory.push转到相应的响应页面。但是,这在 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 的函数重定向到 Cart 页面?

398

您可以在组件之外使用history方法。

首先,创建一个history对象the history package

// 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中看到一个略有不同的示例。

390

React Router v4 与 v3(及更早版本)根本不同,您不能像以前那样做browserHistory.push()

This discussion似乎相关,如果你想要更多的信息:

创建一个新的browserHistory不会工作,因为<BrowserRouter>创建自己的历史实例,并侦听的变化,所以一个不同的实例将改变 URL,但不更新<BrowserRouter>

browserHistory在 v4 中不被 react-router 暴露,仅在 v2 中暴露。

相反,你有几个选项来做到这一点:

使用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);

查看official documentation了解更多信息:

您可以通过 withRouter 高阶组件访问history对象的属性和最接近的<Route>match。每当路由更改时,withRouter 将使用与<Route>渲染道具相同的道具重新渲染其组件:{ match, location, history }

使用contextAPI

使用上下文可能是最简单的解决方案之一,但作为一个实验性的 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");
  }
  ...
}

查看上下文中的official documentation

如果你希望你的应用程序是稳定的,不要使用上下文。它是一个实验性的 API,它很可能会在 React 的未来版本中中断。

如果您坚持使用上下文,尽管有这些警告,请尝试将上下文的使用隔离到一个小区域,并尽可能避免直接使用上下文 API,以便在 API 更改时更容易升级。

117

现在使用 react-router v5,您可以使用 useHistory 钩子,如下所示:

import { useHistory } from "react-router-dom";
function HomeButton() {
  let history = useHistory();
  function handleClick() {
    history.push("/home");
  }
  return (
    <on type="on" onClick={handleClick}>
      Go home
    </on>
  );
}

阅读更多:https://reacttraining.com/react-router/web/api/Hooks/usehistory

41

React Router 4 中最简单的方法是使用

this.props.history.push('/new/url');

但是要使用此方法,您的现有组件应该可以访问history对象。我们可以通过

如果您的组件直接链接到Route,那么您的组件已经可以访问history对象。

eg:

<Route path="/profile" component={ViewProfile}/>

这里ViewProfile可以访问history

如果没有直接连接到Route

eg:

<Route path="/users" render={() => <ViewUsers/>}

然后我们必须使用withRouter,一个更高阶的函数来扭曲现有的组件。

InsideViewUserscomponent import { withRouter } from 'react-router-dom'; export default withRouter(ViewUsers);

现在,您的ViewUsers组件可以访问history对象。

UPDATE

2-在这种情况下,将所有路由props传递给您的组件,然后即使没有HOC,我们也可以从组件访问this.props.history

eg:

<Route path="/users" render={props => <ViewUsers {...props} />}

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(14)
如何解决“指定的服务已被标记为删除”错误(the specified service is marked for deletio
上一篇
为什么iOS拒绝LetsEncrypt支持的证书
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(32条)