React / Redux / Reselect-使用选择器同步还是异步将状态映射到道具?

时间:2019-07-26 19:41:17

标签: reactjs redux react-redux redux-saga reselect

在我们的项目中,我们将react-reduxreselectredux-saga一起使用

在商店中,我有一个selectedStageId和一个stages数组,以及一个记忆化的选择器,该选择器根据ID查找并返回正确的阶段。

此选择器以this.props.selectedStage的形式映射到我的一个组件道具,在我的一个onClick处理程序中,我调度了一个操作,将selectedStageId更新为新选择的UI项的ID,然后尝试将新的selectedStage传递给编辑方法...

但是,即使我添加了断点并验证了我的reducer和selecters都已使用新的id进行了调用,新的selectedStage值仍未在组件的props上同步更新……而是{{ 1}}仍引用先前的值...

示例:

this.props.selectedStage

我已经阅读到redux通常是同步的,但是redux-saga可能以某种方式使它异步...但是,由于我已经验证了reducer和选择器都被同步调用,所以似乎这个问题位于其他地方,也许在connect实际将映射状态更新为props时...

任何人都可以提供一些有关如何以正确方式实现此目标的见识吗?

谢谢!

乔什

更新

这是我的减速器和选择器的相关位...

reducer.ts

onItemSelect = (stageId: number): void => {

  // updateSelectedStageId() is a mapped dispatch method that updates
  // selectedStageId in the store

  this.props.updateSelectedStageId(stageId);

  // I have debugged the above dispatched action and verified that
  // both the reducer and selector are being called with the new
  // stageId, and the selector is executing and returning the correct
  // new stage object before the next line is processed...

  this.editStage(this.props.selectedStage;); // <-- wrong value

  // this.props.selectedStage is the mapped memoized selector that
  // returns the target stage based on the selectedStageId, but
  // here it still references the previous value, not the new one
}

selectors.ts

import produce from 'immer';

const initialState = {
  selectedStageId: -1,
  stages: []
}

export const appReducer = (state = initialState, action) => {
  return produce(state, (draftState) => {
    switch (action.type) {
      case ActionType.UpdateSelectedStageId
        draftState.selectedStageId = action.id;
        break;
    }
  });
}

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题(实际上几乎一样)today

每个状态的更改(是否为Redux)都是异步的。您实际上不能相信该值将被更新。

  

触发同步动作并不意味着它在当前渲染阶段是同步的。因此,您的应用将分派操作,完成渲染,然后新的redux状态将触发重新渲染。

dispatch({type: CHANGE_VALUE, value : newValue})
console.log(value) //oldValue

状态get会同步更新,但是React只会在下一次渲染时才知道该更改。

因此,只需使用您要分派操作的值即可:

onItemSelect = (stageId: number): void => {

  this.props.updateSelectedStageId(stageId);

  this.editStage(stageId)

}