如何以编程方式从React Router 4.0中的事件处理程序导航到路由?

时间:2017-03-24 05:57:30

标签: javascript reactjs router

我需要在活动成功后导航到路线。 自从以前的版本以来,这似乎已经改变了 以前我们会这样做:

import { browserHistory } from 'react-router';
...
handleClick(){
  doSomething();
  browserHistory.push('/some/path');
}

4 个答案:

答案 0 :(得分:8)

此示例适用于react-router和react-router-dom v4.0.0

我们有3个组成部分:

  • App.js - 包含组件1和组件2
  • Component1.js - 没有包裹在路线中并且将始终被渲染,但是这里没有“路线道具”的引用 - (历史,位置,匹配......)
  • Component2.js - 仅在路线位置匹配时呈现。需要注意的是,此组件将使用“路径道具”进行渲染

要以编程方式导航,您可以使用react-router history对象。

this.props.history.push('path');

对于通过Route呈现的组件,这将立即起作用,因为这些组件已经可以访问路径道具(历史记录)。在我们的示例中,这是 Component2 。但是,对于未通过Route呈现的组件(例如Component1),您需要将其包装在withRouter中,以便您访问历史记录对象。

<强> App.js

import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';

import Component1 from './Component1';
import Component2 from './Component2';

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <div>
          <Component1 />
          <Route path="/render1" render={() => <div>Rendered from Component1</div>} />
          <Route path="/" component={Component2} />
          <Route path="/render2" render={() => <div>Rendered from Component2</div>} />
        </div>
      </BrowserRouter>
    )
  }
}

export default App;

<强> Component1.js

import React from 'react';
import { withRouter } from 'react-router';

class Component1 extends React.Component {

  handleButtonClick() {
    this.props.history.push('/render1');
  }

  render() {
    return (
      <div>
        <h1>Component 1</h1>
        <button onClick={this.handleButtonClick.bind(this)}>Component 1 Button</button>
      </div>
    );
  }
}

const Component1WithRouter = withRouter(Component1);
export default Component1WithRouter;

对于 Component1 ,我们将其包装在 withRouter 中,然后导出返回的包装对象。一些问题,请注意,在 App.js 中,我们仍然将其引用为 Component1 而不是 Component1WithRouter

<强> Component2.js

import React from 'react';

class Component2 extends React.Component {

  handleButtonClick() {
    this.props.history.push('/render2');
  }

  render() {
    return (
      <div>
        <h1>Component 2</h1>
        <button onClick={this.handleButtonClick.bind(this)}>Component 2 Button</button>
      </div>
    );
  }
}

export default Component2;

对于Component2,历史对象已经可以从 this.props 获得。你只需要调用push函数。

答案 1 :(得分:0)

只需渲染一个redirect组件:

import { Redirect } from 'react-router';
// ...
<Redirect to="/some/path" />

请参阅此处的文档:https://reacttraining.com/react-router/core/api/Redirect

答案 2 :(得分:0)

我非常感谢CodinCat的回答,因为他帮我解决了一个不同的错误,但我找到了一个更正确的解决方案:

在React Router 4.0中(我不知道以前的版本)路由器将历史对象传递给组件(即:this.props.history)。您可以将您的网址推送到该数组以重定向:

this.props.history.push('/dogs');

在我的情况下,我有两个级别的组件,路由器称为名为LoginPage的组件,而LoginPage称为名为Login的组件。如果你传递它,你将只在你的子对象的道具中有历史对象:

<Router>
  <Route path="/dogs" component={DogsPage}/>
  <Route path="/login" component={LoginPage}/>
</Router>

const LoginPage = (props) => {
  // Here I have access to props.history
  return (
    <div>
      <Login history={props.history} />
    </div>
  )
}

const Login = (props) => {
  function handleClick(){
    // Now we can simply push our url onto the history and the browser will update
    props.history.push('/dogs');
  }
  return (
    <div>
      <button onClick={handleClick}>Click to Navigate</button>
    </div>
  )
}

我知道上面的例子有点做作,因为在这种情况下使用链接会更容易,但我这样做的例子是为了保持简洁。您可能需要以这种方式导航的原因有很多。在我的情况下,我正在做一个graphQL请求,并希望在一个人成功登录后导航到主页。

答案 3 :(得分:0)

如果您使用的是“功能组件”和挂钩,则不要使用props,而应使用useHistory()函数:

import {useHistory} from 'react-router-dom';

export default function MyFunctionComponent() {
    const history = useHistory();

    const myEventHandler = () => {
        // do stuff
        history.push('/newpage');
    };

    // ...
}