当前位置: 首页 > 面试题库 >

使用React Router V4以编程方式导航

通煜祺
2023-03-14
问题内容

我刚刚react-router从v3 替换为v4。
但是我不确定如何以编程方式在的成员函数中进行导航Component。即在handleClick()功能上我想导航到/path/some/where处理一些数据后。我曾经通过以下方式做到这一点:

import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')

但是我在v4中找不到这样的接口。
如何使用v4导航?


问题答案:

如果您定位到浏览器环境,则需要使用react-router-dompackage而不是react- router。他们按照相同的方法作出反应那样,以核心分开,( react)和特定于平台的代码,( react-domreact- native用细微的差别,你并不需要安装两个独立的包),这样的环境包包含一切你需要。您可以通过以下方式将其添加到项目中:

yarn add react-router-dom

要么

npm i react-router-dom

您需要做的第一件事是<BrowserRouter>在应用程序中提供一个作为最顶层的父组件。<BrowserRouter>使用HTML5
historyAPI并为您管理它,因此您不必担心自己实例化并将其<BrowserRouter>作为道具传递给组件(就像在以前的版本中一样)。

在V4中,要以编程方式进行导航,您需要访问history对象(可通过React 进行访问)context,只要您将<BrowserRouter>
提供程序
组件作为应用程序中最顶层的父对象即可。该库通过上下文公开router本身包含history为属性的对象。该history接口提供多种导航方法,比如pushreplacegoBack,等等。您可以在此处检查属性和方法的完整列表。

给Redux / Mobx用户的重要说明

如果您将redux或mobx用作应用程序中的状态管理库,则可能遇到了组件问题,这些组件应该是位置感知的,但在触发URL更新后不会重新呈现

这是因为使用上下文模型react-router传递location给组件。

connect和observer都创建了组件,这些组件的shouldComponentUpdate方法对当前道具和下一个道具进行了浅层比较。只有更改了至少一个道具后,这些组件才会重新渲染。这意味着,为了确保它们在位置更改时更新,需要为它们提供一个在位置更改时更改的道具。

解决此问题的2种方法是:

  • 连接的 组件包裹在无路可走的地方<Route />。当前location对象是a <Route>传递给它渲染的组件的道具之一
  • 连接的 组件与withRouter高阶组件包装 在一起 ,实际上其效果和注入location与道具相同

抛开这些,有四种编程方式进行导航,并按建议进行排序:

1.-使用<Route>组件

它提倡一种声明式风格。在v4之前,<Route />组件被放置在组件层次结构的顶部,必须事先考虑您的路由结构。但是,现在您可以在树中的 任何位置*
拥有<Route>组件,从而使您可以更好地控制根据URL进行有条件的呈现。向组件注入,并作为道具。导航方法(如,,…)都可以作为属性对象。
*Route``match``location``history``push``replace``goBack``history

有3种方法可以Route通过使用componentrenderchildren道具来用a渲染某些事物,但在同一内不要使用多个Route。选择取决于用例,但是基本上前两个选项仅在path匹配url位置时才呈现组件,而children无论路径是否匹配位置,都将呈现组件(可用于基于URL调整UI匹配)。

如果要自定义组件渲染输出
,则需要将组件包装在函数中并使用render选项,以便将所需的其他道具matchlocation和除外)传递给组件history。一个例子来说明:

import { BrowserRouter as Router } from 'react-router-dom'

const ButtonToNavigate = ({ title, history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    {title}
  </button>
);

const SomeComponent = () => (
  <Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)

const App = () => (
  <Router>
    <SomeComponent /> // Notice how in v4 we can have any other component interleaved
    <AnotherComponent />
  </Router>
);

2.-使用withRouterHoC

这个更高阶的成分将注入与相同的道具Route。但是,它带有一个限制,即每个文件只能有1个HoC。

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

const ButtonToNavigate = ({ history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    Navigate
  </button>
);


ButtonToNavigate.propTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired,
  }),
};

export default withRouter(ButtonToNavigate);

3.-使用Redirect组件

渲染<Redirect>会导航到新位置。但是请记住, 默认情况下 ,当前位置会被新位置替换,例如服务器端重定向(HTTP
3xx)。新位置由toprop 提供,可以是字符串(重定向到的URL)或location对象。如果您想 将新条目推送到历史记录中
,则还传递一个push道具并将其设置为true

<Redirect to="/your-new-location" push />

4.- router通过上下文手动访问

有点气is,因为上下文仍然是一个实验性的API,它可能会在React的未来版本中中断/更改

const ButtonToNavigate = (props, context) => (
  <button
    type="button"
    onClick={() => context.router.history.push('/my-new-location')}
  >
    Navigate to a new location
  </button>
);

ButtonToNavigate.contextTypes = {
  router: React.PropTypes.shape({
    history: React.PropTypes.object.isRequired,
  }),
};

不用说,还有一些其他路由器组件将用于非浏览器生态系统,例如 在内存<NativeRouter>中复制导航堆栈并定位到React
Native平台(可通过软件包获得)。 __react-router-native

有关更多参考,请随时查看官方文档。该库的一位合著者还制作了一个视频,其中对React-
router v4进行了非常酷的介绍,重点介绍了一些主要更改。



 类似资料:
  • 问题内容: 通过使用我可以使用元素创建由React Router本机处理的链接。 我在内部看到它的呼唤。 我想导航。不是来自链接,而是来自下拉菜单(例如)。如何在代码中执行此操作?什么啊 我看到了mixin,但是如果没有,我可以这样做吗? 问题答案: 带有钩子的React Router v5.1.0 如果您使用React> 16.8.0和功能组件,则React Router> 5.1.0中会有一个

  • 使用 lavas init 创建的模板项目中,在以下场景下都会以编程方式使用 Lavas: server.dev.js 开发环境下的 SPA/SSR 模式。 server.prod.js 生产环境下的 SSR 模式。 可见以编程方式使用 Lavas 的主要场景就是 SSR 模式,而在 SPA 模式下仅仅是供开发服务器使用。因此,如果开发者选择了 SSR 模式,阅读下面的内容将十分有帮助: 如何选择

  • 问题内容: 我将Wicket与Wicket Auth Project一起用于表示层,因此将其与Spring Security集成在一起。这是Wicket调用的身份验证方法: 我的Spring Security XML配置的内容(里面)是: 2.3.6节。参考文档的会话固定攻击防护说: 会话固定攻击是一种潜在的风险,恶意攻击者有可能通过访问站点来创建会话,然后诱使另一个用户以相同的会话登录(通过向他

  • 问题内容: 我一直在寻找这种解决方案已有一段时间,但是没有任何解决方案。例如一个解决方案是 此代码将添加带有“停止”图像的按钮。就像这样,还有其他解决方案,例如“搜索,刷新”等。但是 ,如果我想以编程方式在想要的图像上添加按钮,该怎么办? 问题答案: 自定义按钮图片,未设置按钮框: 您可以使用指定的图像和其他属性来初始化新项目。 检查此Apple文档。参考 UIBarButtonItem具有使用按

  • 问题内容: 我正在尝试使用导航栏(“后退”按钮,标题等)和选项卡栏(底部的工具栏)制作一个应用程序。我使用的是子视图,因此不必担心状态栏,导航栏,标签栏的高度等问题。但是我认为这给我带来了麻烦,因为我似乎无法弄清楚如何设置导航栏和标签栏。 这就是我所拥有的。我究竟做错了什么? AppDelegate.h AppDelegate.m ViewController.h ViewController.m

  • 问题内容: 我有一个带有标题的导航栏。当我双击文本以将其重命名时,它实际上说这是一个导航项,所以可能就是这样。 我正在尝试使用代码来更改文本,例如: 那显然不是我的代码,只是显示了它是如何工作的。 因此,每当我按下按钮时,我都希望标题更改。 问题答案: 您可以通过更改显示的视图控制器的标题来更改标题: 通常,这是在视图控制器上加载视图时完成的: 但是,这仅在将视图控制器嵌入UINavigation