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

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

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

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


当前回答

只需使用useNavigate,即可使用最新版本的react

新文件.js

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

const Newfile = () => {
    const navigate = useNavigate();
   
    ....

    navigate("yourdesiredlocation");

    ....
}

export default Newfile;

在代码中使用上述的useNavigate功能。

其他回答

这可能不是最好的方法,但。。。使用react router v4,下面的TypeScript代码可以为一些人提供一些想法。

在下面的渲染组件(例如LoginPage)中,可以访问router对象,只需调用router.transitionTo('/home')即可导航。

导航代码取自。

“react router”:“^4.0.0-2”,“反应”:“^15.3.1”,

从“react Router/BrowserRouter”导入路由器;从“react History/BrowserHistory”导入{History};从“history/createBrowserHistory”导入createHistory;consthistory=createHistory();接口MatchWithPropsInterface{component:React.component的类型,router:路由器,历史:历史,确切地?:任何图案:字符串}类MatchWithProps扩展React.Component<MatchWithPropsInterface,any>{render(){返回(<Match{…this.props}render={(matchProps)=>(React.createElement(this.props.component,this.props))}/>)}}ReactDOM.渲染(<路由器>{({路由器})=>(<div><MatchWithProps justly pattern=“/”component={LoginPage}router={router}history={history}/><MatchWithProps pattern=“/login”component={LoginPage}router={router}history={history}/><MatchWithProps pattern=“/home”component={homepage}router={router}history={history}/><缺少组件={NotFoundView}/></div>)}</路由器>,document.getElementById('app'));

React路由器v6+答案

TL;DR:您可以使用新的useNavigate钩子。

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

function Component() {
  let navigate = useNavigate();
  // Somewhere in your code, e.g. inside a handler:
  navigate("/posts"); 
}

useNavigate钩子返回一个可用于编程导航的函数。

反应路由器文档中的示例

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 });
    // replace: true will replace the current entry in 
    // the history stack instead of adding a new one.

  }

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

React Router 5.1.0+应答(使用钩子和React>16.8)

您可以使用Functional Components上的useHistory挂钩,并以编程方式导航:

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

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

React Router 4.0.0+答案

在4.0及以上版本中,将历史记录用作组件的道具。

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

注意:如果<Route>未呈现组件,则此.props.history不存在。您应该使用<Route path=“…”component={YourComponent}/>在YourComponent中具有this.props.history

React路由器3.0.0+答案

在3.0及以上版本中,将路由器用作组件的道具。

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

React路由器2.4.0+答案

在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+答案

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

也就是说,如果您希望切换到新模式,路由器内有一个browserHistory模块,您可以使用

从“react router”导入{browserHistory}

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

browserHistory.push('/some/path')

进一步阅读:历史和航行


React Router 1.x.x答案

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

这个问题的主要变化是从导航混合到历史。现在它使用浏览器历史记录API来更改路由,因此我们将从现在开始使用pushState()。

下面是使用Mixin的示例:

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

请注意,此历史记录来自rackt/History项目。不是来自React Router本身。

如果您出于某种原因(可能是因为ES6类)不想使用Mixin,那么您可以从this.props.history中访问从路由器获得的历史记录。它将仅对路由器渲染的组件可用。因此,如果您想在任何子组件中使用它,则需要通过props将其作为属性传递。

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

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

它建议获取一个引用history=createHistory(),并对其调用replaceState。

React路由器0.13.x答案

我也遇到了同样的问题,只能通过带有react路由器的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>);
  }
});

我能够在不需要访问.context的情况下调用transitionTo()

或者你可以试试ES6高级课程

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路由器Redux注意:如果您使用的是Redux,还有一个项目叫做React Router Redux为您提供redux绑定ReactRouter,使用与React Redux会

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

探索以下方法:

推(位置)替换(位置)go(数字)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>

也许不是最好的解决方案,但它可以完成任务:

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

// Create functional component Post
export default Post = () => (
    <div className="component post">

        <button className="button delete-post" onClick={() => {
            // ... delete post
            // then redirect, without page reload, by triggering a hidden Link
            document.querySelector('.trigger.go-home').click();
        }}>Delete Post</button>

        <Link to="/" className="trigger go-home hidden"></Link>

    </div>
);

基本上,与一个操作相关的逻辑(在本例中为删除后操作)最终将调用重定向触发器。这并不理想,因为您将在标记中添加DOM节点“触发器”,以便在需要时方便地调用它。此外,您将直接与DOM交互,这在React组件中可能是不需要的。

不过,这种类型的重定向并不经常需要。因此,在组件标记中添加一两个额外的隐藏链接并不会造成太大的伤害,特别是如果您为它们提供了有意义的名称。

如果您使用的是更新版本的React,那么使用“useHistory”钩子是最好的选择。

根据JoséAntonio Postigo和Ben Wheeler先前的回答:

新奇之处?用TypeScript编写并使用修饰符或静态属性/字段

import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";

export interface INavigatorProps {
    router?: ReactRouter.History.History;
}

/**
 * Note: goes great with mobx
 * @inject("something") @withRouter @observer
 */
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
    navigate: (to: string) => void;
    constructor(props: INavigatorProps) {
        super(props);
        let self = this;
        this.navigate = (to) => self.props.router.push(to);
    }
    render() {
        return (
            <ul>
                <li onClick={() => this.navigate("/home")}>
                    Home
                </li>
                <li onClick={() => this.navigate("/about")}>
                    About
                </li>
            </ul>
        )
    }
}

/**
 * Non decorated
 */
export class Navigator2 extends Component<INavigatorProps, {}> {

    static contextTypes = {
        router: React.PropTypes.object.isRequired,
    };

    navigate: (to: string) => void;
    constructor(props: INavigatorProps, context: any) {
        super(props, context);
        let s = this;
        this.navigate = (to) =>
            s.context.router.push(to);
    }
    render() {
        return (
            <ul>
                <li onClick={() => this.navigate("/home")}>
                    Home
                </li>
                <li onClick={() => this.navigate("/about")}>
                    About
                </li>
            </ul>
        )
    }
}

无论今天安装了什么npm。

“react router”:“^3.0.0”和“@types/react router”:“^2.0.41”