使用react router,我可以使用Link元素来创建由react route本地处理的链接。

我看到它在内部调用this.context.transitionTo(…)。

我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?

我看到了导航混合,但我可以在没有混合的情况下这样做吗?


当前回答

要以编程方式进行导航,您需要将新的历史推送到组件中的props.history,这样就可以完成以下工作:

//using ES6
import React from 'react';

class App extends React.Component {

  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e) {
    e.preventDefault()
    /* Look at here, you can add it here */
    this.props.history.push('/redirected');
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>
          Redirect!!!
        </button>
      </div>
    )
  }
}

export default App;

其他回答

以下是如何使用带有ES6的react router v2.0.0来实现这一点。react路由器已远离mixin。

import React from 'react';

export default class MyComponent extends React.Component {
  navigateToPage = () => {
    this.context.router.push('/my-route')
  };

  render() {
    return (
      <button onClick={this.navigateToPage}>Go!</button>
    );
  }
}

MyComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}

对于这一个,谁不控制服务器端,因此使用哈希路由器v2:

将历史记录放入单独的文件(例如app_history.js ES6):

import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });

export default appHistory;

并在任何地方使用它!

react router(app.js ES6)的入口点:

import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
  <Router history={appHistory}>
  ...
  </Router>
), document.querySelector('[data-role="app"]'));

任何组件(ES6)内的导航:

import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
  if (err) {
    console.error(err); // login failed
  } else {
    // logged in
    appHistory.replace('/dashboard'); // or .push() if you don't need .replace()
  }
})

上面已经提到,我们可以使用useNavigate()在上一次更新React Router V6(不包括useHistory)中导航

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

const myComponent = () => {
  const navigate = useNavigate();
  navigate('my_url');
  ...
}

但我在这里找不到的是调用导航出React组件,就像将redux saga函数中的页面导航到另一个页面。以防万一,如果你有同样的问题,这是我发现的。

在根组件中(我称之为<App/>)

import { useNavigate } from 'react-router-dom';
import useBus from 'use-bus';

const App = () => {
  const navigate = useNavigate();
  useBus('@@ui/navigate', (action) => navigate(action.payload.url), []);
  ...
}

脱离React组件(在我的例子中是redux saga函数)

import { dispatch } from 'use-bus';

dispatch({ type: '@@ui/navigate', payload: { url: '/404' } });

希望有帮助!

React路由器v4和ES6

您可以使用Router和this.props.history.push。

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

class Home extends Component {

    componentDidMount() {
        this.props.history.push('/redirect-to');
    }
}

export default withRouter(Home);

React路由器v6

我已经有一段时间没有接触过React了,但我想感谢并强调Shimrit Snapir的以下评论:

在React Router 6.0上,<Redirect/>更改为<Navigator/>

React路由器V4

tl:dr;

if (navigate) {
  return <Redirect to="/" push={true} />
}

简单而声明性的答案是,需要将<Redirectto={URL}push={boolean}/>与setState()结合使用

push:boolean-如果为true,重定向将向历史中推送一个新条目,而不是替换当前条目。


import { Redirect } from 'react-router'

class FooBar extends React.Component {
  state = {
    navigate: false
  }

  render() {
    const { navigate } = this.state

    // Here is the important part
    if (navigate) {
      return <Redirect to="/" push={true} />
    }
   // ^^^^^^^^^^^^^^^^^^^^^^^

    return (
      <div>
        <button onClick={() => this.setState({ navigate: true })}>
          Home
        </button>
      </div>
    )
  }
}

这里有一个完整的例子。在这里阅读更多信息。

PS.该示例使用ES7+属性初始化器初始化状态。如果你感兴趣的话,也可以看看这里。