如何响应 redux 中的状态变化并派发另一个动作?

Posted

技术标签:

【中文标题】如何响应 redux 中的状态变化并派发另一个动作?【英文标题】:How to respond to state change in redux and dispatch another action? 【发布时间】:2016-11-01 20:36:29 【问题描述】:

有人可以告诉我如何使用 react-redux 执行以下操作:

组件 A 调度更新状态的操作(异步)

组件 B(不是 A 的子组件)需要能够检测到状态何时发生变化并调度另一个动作。

我的问题是当我尝试在组件 B 中执行调度操作 2 时,状态仍处于初始状态并且没有更新。

我也尝试在 componentWillUpdate 中调度动作 2,但是,这会创建一个无限循环,因为第二个动作也会更新状态(并且也是异步的)

或多或少是这样的:

//----- Component A
class ComponentA extends React.Component 
  constructor(props) 
    super(props);
    this.props.dispatch(loadEvents()); // loadEvents is async and will   update state.eventsState
  


const mapStateToProps = function (state) 
  return 
    eventsState: state.eventsState,
  ;
;

export default connect(mapStateToProps)(ComponentA);


//----- Component B
class ComponentA extends React.Component 
  constructor(props) 
    super(props);
    props.dispatch(getEventUsers(props.eventsState.eventId)); // the eventsState is in initial state here (empty)...where do I call getEventUsers?
  

  componentWillUpdate(nextProps) 
    nextProps.dispatch(getEventUsers(props.eventsState.eventId)) // Creates an infinite loop, getEventUsers also updates state
  


const mapStateToProps = function (state) 
  return 
    eventsState: state.eventsState,
  ;
;

export default connect(mapStateToProps)(ComponentA);

【问题讨论】:

组件 B 应该只考虑开始加载和完成加载之间的时间。它可以显示一个微调器或什么都没有(空 div)。即使您的 loadEvents 减速器是同步的,也不能保证它首先被调度。 React 独自决定何时调用各种函数,例如 shouldComponentUpdate,甚至是你的组件构造函数。 【参考方案1】:

如果不查看您的 Redux 代码,我会说您的 Component B 在构造函数中获取空数据,因为它大约在 Component A 的同时实例化,此时由 Component A 构造函数发起的异步请求仍然存在进行中。

当异步请求完成时,您的 Redux 应该触发一个包含接收到的数据的操作。然后你的 reducer 将这些数据置于 state 中,这反过来会改变你连接的组件的 props 并强制它们重新渲染。

只有当 props.eventState.eventId 存在并且已经改变时,你才应该调度 getEventUsers。

【讨论】:

有道理,谢谢!您将如何检查 props.eventState.eventId 是否存在?我应该将 nextProps 与 componentWillUpdate 中的 this.props 进行比较吗? 仅将 this.props 与 nextProps 进行比较的问题在于,如果您的 eventUsers 包含在您的 eventState 中,您将在加载用户时获得一个新的 eventState 引用,因此它们会有所不同,即使event 相同,导致再次获取 eventUsers。比较 id 可确保您确实在查看不同的事件。如果您确实想在某个时候重新加载同一事件的数据,这可能是一个问题。我建议规范您的状态:将所有加载的用户保存在一个单独的对象中,将他们的 ID 映射到用户数据,然后在事件对象中通过 ID 引用它们。

以上是关于如何响应 redux 中的状态变化并派发另一个动作?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 redux 派发一个动作并返回一个承诺?

Redux

如何在 Redux 中完成另一个同步操作时分派一个操作

redux 状态变化时如何导航?

当一个动作被派发时做某事

调度动作以响应另一个动作