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

mit*_*man 10 html5-history reactjs react-router react-thunk react-router-dom

我试图了解(v5)包和之间的区别,BrowserRouter以及Routerreact-router-dom下面的示例有什么区别。

该文件说:

BrowserRouter A,使用HTML5历史记录API(pushState,replaceState和popstate事件)使UI与URL保持同步。

来源: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));
    })
  };
};
Run Code Online (Sandbox Code Playgroud)

history 定义为此模块:

import { createBrowserHistory } from 'history';

export default createBrowserHistory();
Run Code Online (Sandbox Code Playgroud)

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

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

...

const App = () => (
  <Router history={history}>
     ...
  </Router>
);
Run Code Online (Sandbox Code Playgroud)

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

如果我导入Router而不是BrowserRouter,则可以使用:

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

// Does work:
import { Router } from 'react-router-dom';
Run Code Online (Sandbox Code Playgroud)

小智 11

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

  • 这篇[站外帖子](https://www.techiediaries.com/react/react-router-5-4-tutorial-examples/)解释了这些差异。“使用 React router v5,路由不再是集中式的,而是成为应用程序布局和 UI 其余部分的一部分。” “如果您使用的是可以处理动态 URL 的动态服务器,那么您需要使用 BrowserRouter 组件,但如果您使用的是仅提供静态文件的服务器,那么在这种情况下需要使用 HashRouter 组件。” (4认同)
  • 与“Router”相比,“BrowserRouter”如何自动处理它? (2认同)

Xit*_*ang 6

您可以通过 useHistory 钩子访问历史记录来为 BrowserRouterlet history = useHistory();执行history.push()

查看HTML5 History API 文档,似乎 history API 会自动为用户保留状态。假设您最初在第 1 页,并且第 1 页有一个页面外观 A。您执行了一些将第 1 页外观更改为 B 的操作。如果您现在移动到第 2 页,当您单击浏览器上的后退按钮时,您将直接返回第 1 页。历史 API 会保留您的状态,因此它知道将 Outlook B 呈现给您,这就是使用BrowserRouter. 虽然我不是 100% 肯定,但我想Browser没有这个功能,在这种情况下,当你被引导回第 1 页时,它会呈现 Outlook A。这不是真的。我不确定其中的区别。