BrowserRouter与带有history.push()的路由器

时间:2019-06-21 17:14:53

标签: reactjs react-router react-router-dom html5-history react-thunk

我试图了解BrowserRouter(v5)软件包的Routerreact-router-dom之间的区别,以及它对下面的示例有何不同。

文档说:

  

BrowserRouter   使用HTML5历史记录API(pushState,   replaceState和popstate事件),以使您的用户界面与   网址。

来源:https://reacttraining.com/react-router/web/api/BrowserRouter

  

路由器   所有路由器组件的通用底层接口。通常   应用将改为使用高级路由器之一:BrowserRouter,HashRouter,MemoryRouter,NativeRouter,StaticRouter

来源:https://reacttraining.com/react-router/web/api/Router

据我了解,我应该为我的HTML5浏览器应用程序使用 BrowserRouter ,并且到目前为止,我一直在这样做。

history.push(...)示例:

我正试图在重击中执行history.push('/myNewRoute')

import history as './history';

...

export function someAsyncAction(input) {
  return dispatch => {
    fetch(`${API_URL}/someUrl`, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ input }),
    }).then(() => {
      history.push('/myNewRoute');
    }).catch((err) => {
      dispatch(setError(err));
    })
  };
};

history定义为此模块:

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

并且history也传递到我的路由器:

import { BrowserRouter as Router } from 'react-router-dom';
import history as './history';

...

const App = () => (
  <Router history={history}>
     ...
  </Router>
);

问题:history.push()将更新浏览器栏中的URL,但不会在路线后面显示组件。

如果我导入的是Router而不是BrowserRouter,那么它将起作用:

// Does not work:
import { BrowserRouter as Router } from 'react-router-dom';

// Does work:
import { Router } from 'react-router-dom';

3 个答案:

答案 0 :(得分:3)

您可以通过useHistory钩子let history = useHistory();访问历史记录,以对BrowserRouter执行history.push()

看着HTML5 History API documentation,历史记录API似乎自动为用户保留了状态。假设您最初在页面1上,页面1的页面前景为A。您执行了一些操作,将页面1的前景更改为B。如果现在移至页面2,则在浏览器中单击“后退”按钮时,直接返回到页面1。HistoryAPI保留您的状态,因此它知道向您呈现Outlook B,因此这是使用BrowserRouter的优势。尽管我不确定100%,但我想Browser没有此功能,在这种情况下,当您返回到第1页时它将呈现Outlook A。这是不正确的。我不确定有什么区别。

答案 1 :(得分:0)

BrowserRouter会忽略历史记录道具,因为它会自动为您处理历史记录。如果您需要访问React组件之外的历史记录,则可以使用Router

答案 2 :(得分:0)

我也有同样的问题。

BrowserRouteruseHistory() 钩子已用于我的组件。 createBrowserHistory() 已用于 redux-saga。但是,页面并没有像你的情况那样被 redux-saga 移动。

另外,我的源代码是使用 BrowserRouter 开发的,我不想将其替换为 Router 组件。

由于我的拙劣调查,我发现两个历史对象是不同的。 (我将它们与 if== 进行了比较。)我想这就是原因。

为了解决这个问题,我将 useHistory() 得到的 history 对象的引用保存到一些全局实用程序代码中,并在 redux-saga 代码中使用它。然后,它运行良好。

我认为这不是最好的方法,但我还没有找到最好的官方方法。