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

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

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

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


当前回答

仅使用浏览器api,独立于任何库

const navigate = (to) => {
    window.history.pushState({}, ",", to);
  };

这不会导致整页刷新。您仍然可以使用浏览器后退按钮

其他回答

随着React Router v4即将推出,现在有了一种新的实现方式。

import { MemoryRouter, BrowserRouter } from 'react-router';

const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;

<Router location="/page-to-go-to"/>

react lego是一个示例应用程序,展示了如何使用/更新react router,它包括导航应用程序的示例功能测试。

更新:2022:使用useNavigate的React Router v6.6.1

useHistory()钩子现已弃用。如果您使用的是React Router 6,编程导航的正确方法如下:

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

function HomeButton() {
  const navigate = useNavigate();

  function handleClick() {
    navigate("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

带挂钩的React Router v5.1.0

如果您使用的是React>16.8.0和功能组件,则React Router>5.1.0中有一个新的useHistory钩子。

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

function HomeButton() {
  const history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

反应路由器v4

使用React Router的v4,有三种方法可以用于组件内的编程路由。

使用withRouter高阶组件。使用合成并渲染<Route>使用上下文。

React Router主要是历史库的包装器。历史记录处理与浏览器窗口的交互。历史记录为您提供浏览器和哈希历史记录。它还提供了一个内存历史,对于没有全局历史的环境非常有用。这在使用Node进行移动应用程序开发(react native)和单元测试时特别有用。

历史记录实例有两种导航方法:推送和替换。如果您将历史记录视为一个访问位置数组,push将向数组中添加一个新位置,replace将用新位置替换数组中的当前位置。通常,您在导航时需要使用push方法。

在React Router的早期版本中,您必须创建自己的历史实例,但在v4中,<BrowserRouter>、<HashRouter>和<MemoryRouter>组件将为您创建浏览器、哈希和内存实例。React Router使与路由器关联的历史实例的财产和方法通过路由器对象下的上下文可用。

1.使用withRouter高阶组件

withRouter高阶组件将注入历史对象作为组件的属性。这允许您访问push和replace方法,而不必处理上下文。

import { withRouter } from 'react-router-dom'
// this also works with react-router-native

const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    Click Me!
  </button>
))

2.使用合成并渲染<Route>

<Route>组件不仅仅用于匹配位置。您可以渲染无路径路线,它将始终与当前位置匹配。<Route>组件传递与withRouter相同的属性,因此您可以通过历史属性访问历史方法。

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history}) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      Click Me!
    </button>
  )} />
)

3.使用上下文*

但你可能不应该

最后一个选项是只有当您觉得使用React的上下文模型时才应该使用的选项(React的context API在v16中是稳定的)。

const Button = (props, context) => (
  <button
    type='button'
    onClick={() => {
      // context.history.push === history.push
      context.history.push('/new-location')
    }}
  >
    Click Me!
  </button>
)

// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  })
}

1和2是实现的最简单的选择,因此对于大多数用例来说,它们是最好的选择。

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

新文件.js

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

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

    navigate("yourdesiredlocation");

    ....
}

export default Newfile;

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

如果您正在使用哈希或浏览器历史记录,那么您可以

hashHistory.push('/login');
browserHistory.push('/login');

在React Router v4中实现这一点时面临问题的人。

这里有一个从redux操作导航到React应用程序的工作解决方案。

文件history.js

import createHistory from 'history/createBrowserHistory'

export default createHistory()

文件App.js/Route.jsx

import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
 <Route path="/test" component={Test}/>
</Router>

文件*另一个_File.js或redux文件

import history from './history'

history.push('/test') // This should change the URL and rerender Test component

感谢GitHub上的评论:ReactTraining问题评论