一尘不染

使用 React 路由器以编程方式导航

javascript

react-router我可以使用该元素Link创建由反应路由器本机处理的链接。

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

我想做一个导航。不是来自链接,而是来自下拉选择(例如)。我怎样才能在代码中做到这一点?是什么this.context

我看到了Navigationmixin,但我可以不这样做mixins吗?


阅读 297

收藏
2022-02-13

共1个答案

一尘不染

React-Router v6+Answer

您可以使用新的useNavigate挂钩。useNavigatehook 返回一个可用于编程导航的函数。来自反应路由器文档的示例

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

function SignupForm() {
  let navigate = useNavigate();

  async function handleSubmit(event) {
    event.preventDefault();
    await submitForm(event.target);
    navigate("../success", { replace: true });
  }

  return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}

React-Router 5.1.0+Answer(使用钩子和 React >16.8)

您可以使用useHistory功能组件上的钩子并以编程方式导航:

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

function HomeButton() {
  let history = useHistory();
  // use history.push('/some/path') here
};

React-Router 4.0.0+Answer

在 4.0 及更高版本中,使用历史记录作为组件的道具。

class Example extends React.Component {
   // use `this.props.history.push('/some/path')` here
};

注意:如果您的组件不是由 .props 渲染的,则 this.props.history 不存在<Route>。您应该使用<Route path="..." component={YourComponent}/>this.props.history 在 YourComponent

React-Router 3.0.0+Answer

在 3.0 及更高版本中,使用路由器作为组件的道具。

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

React-Router 2.4.0+Answer

在 2.4 及更高版本中,使用更高阶的组件来获取路由器作为组件的道具。

import { withRouter } from 'react-router';

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

// Export the decorated class
var DecoratedExample = withRouter(Example);

// PropTypes
Example.propTypes = {
  router: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  }).isRequired
};

React-Router 2.0.0+Answer

此版本向后兼容 1.x,因此无需升级指南。仅仅通过示例就足够了。

也就是说,如果您想切换到新模式,路由器内部有一个 browserHistory 模块,您可以使用它访问

import { browserHistory } from 'react-router'

现在您可以访问浏览器历史记录,因此您可以执行推送、替换等操作……例如:

browserHistory.push('/some/path')

进一步阅读: 历史导航


React-Router 1.xxAnswer

我不会详细介绍升级细节。您可以在升级指南中阅读相关内容

关于这里问题的主要变化是从 Navigation mixin 到 History 的变化。现在它使用浏览器 historyAPI 来改变路由,所以我们pushState()将从现在开始使用。

下面是一个使用 Mixin 的例子:

var Example = React.createClass({
  mixins: [ History ],
  navigateToHelpPage () {
    this.history.pushState(null, `/help`);
  }
})

请注意,这History来自rackt/history项目。不是来自 React-Router 本身。

如果您出于某种原因不想使用 Mixin(可能是因为 ES6 类),那么您可以从this.props.history. 只有路由器渲染的组件才能访问它。因此,如果您想在任何子组件中使用它,则需要通过props.

您可以在他们的1.0.x 文档中阅读有关新版本的更多信息

这是一个专门关于在组件外部导航的帮助页面

它建议获取参考history = createHistory()并调用replaceState它。

React-Router 0.13.x Answer

我遇到了同样的问题,只能使用 react-router 附带的 Navigation mixin 找到解决方案。

我是这样做的

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

let Authentication = React.createClass({
  mixins: [Navigation],

  handleClick(e) {
    e.preventDefault();

    this.transitionTo('/');
  },

  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
});

transitionTo()无需访问即可拨打电话.context

或者你可以试试花哨的 ES6class

import React from 'react';

export default class Authentication extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(e) {
    e.preventDefault();

    this.context.router.transitionTo('/');
  }

  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
}

Authentication.contextTypes = {
  router: React.PropTypes.func.isRequired
};

React-Router-Redux

注意:如果您使用的是 Redux,还有另一个名为 React-Router-Redux的项目为您提供 ReactRouter 的 redux 绑定,使用的方法与React-Redux的方法有些 相同

React-Router-Redux 有一些可用的方法允许从内部动作创建者进行简单的导航。这些对于在 React Native 中拥有现有架构的人特别有用,并且他们希望在 React Web 中使用相同的模式,而样板开销最小。

探索以下方法:

  • push(location)
  • replace(location)
  • go(number)
  • goBack()
  • goForward()

这是使用Redux-Thunk的示例用法:

./actioncreators.js

import { goBack } from 'react-router-redux'

export const onBackPress = () => (dispatch) => dispatch(goBack())

./viewcomponent.js

<button
  disabled={submitting}
  className="cancel_button"
  onClick={(e) => {
    e.preventDefault()
    this.props.onBackPress()
  }}
>
  CANCEL
</button>
2022-02-13