我需要使用我的应用程序url,并根据我的应用程序当前状态的变化做出react .

基本上,我有一个组件,需要在每次url更改时更新它的状态.状态是通过redux的props 传递给装饰师的,就像这样

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

目前,我正在使用componentWillReceiveProps生命周期方法来响应来自react-router的url更改,因为当url在此过程中发生更改时,react-router将向处理程序传递新的props .props .params和这个.props .查询——这种方法的主要问题是,我在这个方法中启动了一个操作来更新状态——然后它会go 传递新的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);
    }
  }

是否有一种基于路由转换触发操作的标准方法,或者我是否可以将存储的状态直接连接到组件的状态,而不是通过props 传递?我曾try 使用WillTransition静态方法,但我没有访问该方法的权限.props .派过go .

推荐答案

好吧,我最终在redux的github页面上找到了答案,所以我将在这里发布.希望它能帮别人省go 一些痛苦.

@我认为这个问题有两个方面.首先,componentWillReceiveProps()并不是响应状态变化的理想方式——主要是因为它迫使您必须进行必要的思考,而不是像Redux那样进行react .解决方案是将当前路由信息(位置、参数、查询)存储在存储区内.然后,您的所有状态都在同一个位置,您可以使用与其他数据相同的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 select={state => ({ filter: getFilters(store.router.params) })} />

问题的第二部分是,您需要一种方法来对视图层之外的重排状态更改做出react ,例如,对路由更改触发一个操作.如果您愿意,您可以继续在您描述的简单 case 中使用componentWillReceiveProps.

不过,对于任何更复杂的问题,如果你愿意的话,我建议你使用RxJS.这正是可观测数据的设计目的——react 式数据流.

要在Redux中实现这一点,首先创建一个可观察的存储状态序列.您可以使用rx的ObservaleFromStore()实现这一点.

EDIT AS SUGGESTED BY 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())的相同功能要简单得多.

Reactjs相关问答推荐

自动化幻灯片放映以防止React中重复过多的正确方法是什么

Formik验证不适用于物料UI自动完成

如何在React中的textarea中显示字符数?

关于同一位置的不同组件实例的react S规则被视为相同组件

下拉Tailwind CSS菜单与怪异beviour

如何处理具有REACTION-REDUX状态的Nextjs路由警卫

无法将react 路由状态从路由传递给子组件

无法使用 Suspense 和 Await 获取数据

Material-UI 和 React Hook 表单不记录值

太多的重新渲染 - React 中的无限循环.如何使用React.effect并使用fetch?

在 Next13 中将 props 传递给 onClick 从服务器到客户端组件

如何更改TimePicker中下拉菜单的背景 colored颜色 和字体 colored颜色 - MUI React

如何在 React.js 中提取 PDF 的内容?

为什么我会收到此错误:无法在我的react 包上读取 null 的属性(读取useState)?

文本的几个词具有线性渐变 colored颜色 - React native

React - 使用 React 显示错误和积极alert

如何使用 React 更改 Material UI 中 ButtonGroup 的 colored颜色 ?

如何使用 React Hook Form 将寄存器作为 props 发送到子组件来收集数据?

意外的标记.您可能需要一个合适的加载器来处理这种文件类型.书?.img? /*#__PURE__*/React.createElement("img",

react 路由dom没有路由匹配位置错误/在路由中制作组件