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

在React Router中触发Redux操作以响应路由转换

晏和风
2023-03-14
问题内容

我在最新的应用程序中使用react-router和redux,并且遇到了一些与基于当前url参数和查询所要求的状态更改有关的问题。

基本上,我有一个组件,每次URL更改时都需要更新其状态。像这样通过装饰器通过redux通过props传递状态

 @connect(state => ({
   campaigngroups: state.jobresults.campaigngroups,
   error: state.jobresults.error,
   loading: state.jobresults.loading
 }))

目前,我正在使用componentWillReceiveProps生命周期方法来响应来自react-
router的url更改,因为当this.props.params和this.props.query中的url更改时,react-
router会将新的props传递给处理程序。这种方法的主要问题是,我正在此方法中触发操作以更新状态-
然后,该状态通过并传递新的props该组件将再次触发相同的生命周期方法-因此基本上创建了一个无穷循环,目前我正在设置一个状态变量以阻止这种情况的发生。

  componentWillReceiveProps(nextProps) {
    if (this.state.shouldupdate) {
      let { slug } = nextProps.params;
      let { citizenships, discipline, workright, location } = nextProps.query;
      const params = { slug, discipline, workright, location };
      let filters = this._getFilters(params);
      // set the state accroding to the filters in the url
      this._setState(params);
      // trigger the action to refill the stores
      this.actions.loadCampaignGroups(filters);
    }
  }

是否有基于路线转换来触发动作的标准方法,还是可以将商店的状态直接连接到组件的状态,而不是通过prop传递它?我尝试使用willTransitionTo静态方法,但无法访问this.props.dispatch。


问题答案:

好吧,我最终在redux的github页面上找到了答案,因此将其发布在这里。希望它可以减轻别人的痛苦。

@deowk我想说,这个问题有两个部分。首先是componentWillReceiveProps()并不是一种响应状态变化的理想方法-
主要是因为它迫使您进行命令式思考,而不是像我们对Redux那样进行被动式思考。解决方案是将当前的路由器信息(位置,参数,查询)存储在商店中。然后,您所有的状态都在同一个地方,您可以使用与其余数据相同的Redux
API对其进行订阅。

诀窍是创建一个在路由器位置更改时将触发的操作类型。在即将推出的React Router 1.0版本中,这很容易:

// routeLocationDidUpdate() is an action creator
// Only call it from here, nowhere else
BrowserHistory.listen(location => dispatch(routeLocationDidUpdate(location)));

现在,您的存储状态将始终与路由器状态同步。这就解决了手动响应查询参数更改和上面组件中的setState()的需求-只需使用Redux的Connector。

<Connector select={state => ({ filter: getFilters(store.router.params) })} />

问题的第二部分是您需要一种对视图层之外的Redux状态更改做出反应的方法,例如响应路径更改而触发操作。如果愿意,您可以继续使用componentWillReceiveProps处理简单情况,例如您描述的情况。

不过,对于更复杂的事情,我建议您使用RxJS(如果您愿意的话)。这正是可观察对象的设计目标-反应性数据流。

要在Redux中执行此操作,请首先创建一个可观察的存储状态序列。您可以使用rx的observableFromStore()执行此操作。

CNP建议的编辑

import { Observable } from 'rx'

function observableFromStore(store) {
  return Observable.create(observer =>
    store.subscribe(() => observer.onNext(store.getState()))
  )
}

然后,只需使用可观察的运算符来订阅特定的状态更改即可。这是成功登录后从登录页面重定向的示例:

const didLogin$ = state$
  .distinctUntilChanged(state => !state.loggedIn && state.router.path === '/login')
  .filter(state => state.loggedIn && state.router.path === '/login');

didLogin$.subscribe({
   router.transitionTo('/success');
});

此实现比使用命令式模式(例如componentDidReceiveProps())的相同功能要简单得多。



 类似资料:
  • 我在最新的应用程序中使用react router和redux,我面临着一些与基于当前url参数和查询所需状态更改相关的问题。 基本上,我有一个组件,需要在每次url更改时更新它的状态。状态是通过redux的道具传递给decorator的,就像这样 目前,我正在使用componentWillReceiveProps生命周期方法来响应来自react-router的url更改,因为当this.props

  • 我正在使用react路由器v4和redux,如果用户未登录,我想使用私有和受保护的路由重定向。 我有一个路由组件: 它是这样实现的: 这是私人路线: 传递prop的最佳方式是什么,如果我连接Routes组件并从那里传递是否可以,或者应该从其他地方传递,或者连接需要它的每个组件并从那里读取?此外,这种方法如何处理嵌套路由,如?谢谢

  • 作为参考,我研究了以下三个问题: 从Flask视图返回JSON响应 使用Flask响应发送JSON和状态代码 返回请求。来自 Flask 的响应对象 如标题所示,我试图从flask post方法返回一个JSON响应。烧瓶路径如下: 在我的web应用程序中,我希望将< code>session-token存储在cookies中的什么位置(目前)。 目前在web端,我有以下代码: 其中 由。鉴于上面列

  • 问题内容: 我正在构建一个React应用,并正在调用一个自定义处理程序库来调用我们的REST API。 在这些(非响应)函数中,我想触发Redux操作以使用端点响应来更新商店,但是如果没有通常的’mapDispatchToProps’/ connect()方法,就无法弄清楚如何触发Redux操作。 这可能吗? 谢谢 问题答案: 为了从您的范围之外进行调度和采取行动,您需要获取商店实例并像这样调用它

  • 问题内容: 我有一个使用redux和react-router的通用react应用程序。 我有以下几种路线: 等等 每个路由都需要来自API的数据。目前,我在Navigation组件中的元素调度了一个async action ,该操作使用来自该路线的API中的数据填充商店。 对于MVP,我只是在路线更改时用新的帖子内容覆盖商店中的内容,这样我们就可以获取API上的所有新内容。 我已经意识到在按钮上设

  • 使用redux和反应路由器,我想访问路由指定的组件以外的组件上的路由参数。 我已经对react-router、redux和react-router-redux进行了如下设置,我想从我的redux存储访问reportId参数。 我已经尝试连接react-redux路由器来存储路由状态,但是我发现除了活动路由的完整路径之外,redux内部没有任何有用的存储。这让我可以选择从redux中的路径解析出re