在当前版本的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的函数重定向到购物车页面?


当前回答

第一步在路由器中包装你的应用程序

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中看到一个稍微不同的例子。

React路由器V4现在允许历史道具如下所示:

this.props.history.push("/dummy",value)

然后,只要位置道具可用,就可以访问该值 State:{value}不是组件状态。

在这种情况下,你将道具传递给你的坦克。所以你可以简单地打电话

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')
    })
  }
}

现在在react-router v5中,你可以像这样使用useHistory钩子:

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>
  );
}

详情请访问:https://reacttraining.com/react-router/web/api/Hooks/usehistory

创建一个带有自己的browserHistory的自定义路由器:

import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

const ExtBrowserRouter = ({children}) => (
  <Router history={history} >
  { children }
  </Router>
);

export default ExtBrowserRouter

接下来,在你定义路由器的根目录上,使用以下命令:

import React from 'react';       
import { /*BrowserRouter,*/ Route, Switch, Redirect } from 'react-router-dom';

//Use 'ExtBrowserRouter' instead of 'BrowserRouter'
import ExtBrowserRouter from './ExtBrowserRouter'; 
...

export default class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <ExtBrowserRouter>
          <Switch>
            ...
            <Route path="/login" component={Login}  />
            ...
          </Switch>
        </ExtBrowserRouter>
      </Provider>
    )
  }
}

最后,在需要的地方导入历史记录并使用它:

import { history } from '../routers/ExtBrowserRouter';
...

export function logout(){
  clearTokens();      
  history.push('/login'); //WORKS AS EXPECTED!
  return Promise.reject('Refresh token has expired');
}