【发布时间】:2019-12-05 03:49:53
【问题描述】:
在我们的项目中,我们使用 react-redux 和 reselect 和 redux-saga
在商店中,我有一个 selectedStageId 以及一个 stages 数组和一个基于 id 查找并返回正确阶段的记忆选择器。
这个选择器作为this.props.selectedStage 映射到我的一个组件道具,并且在我的一个onClick 处理程序中,我调度了一个操作以将selectedStageId 更新为新选择的UI 项的ID,然后尝试将新的selectedStage 传递给编辑方法...
但是,即使我添加了断点并验证了我的减速器和选择器都使用新的 id 调用,新的 selectedStage 值并没有在我的组件的 props 上同步更新...而是 this.props.selectedStage 仍然引用之前的值...
示例:
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
}
我读过 redux 通常是同步的,但是 redux-saga 可能会以某种方式使这个异步......但是,由于我已经验证了 reducer 和 selector 都是同步调用的,所以问题似乎是位于其他地方,可能在 connect 实际将映射状态更新为 props 时...
谁能提供一些关于如何以正确方式完成此任务的见解?
谢谢!
乔什
更新
这是我的减速器和选择器的相关位...
reducer.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;
}
});
}
selectors.ts
import { createSelector } from 'reselect';
const _getSelectedStage = (stages, id) => {
return stages.find((s) => s.id === id);
};
export const selectedStage = createSelector(
[getStages, getSelectedStageId],
_getSelectedStage
);
【问题讨论】:
-
即使 redux 在理想情况下是同步的,React 仍然总是以异步方式更新组件(并提供新的 props)。
-
那么有没有办法,类似于
setState来等待或提供回调,以便在新状态传播回道具后继续执行? -
您可以在
componentDidUpdate中检查props的更改(无论他们的发起者),或者在随后调用的不同redux 操作中移动相关逻辑 -
听起来你的减速器可能处于变异状态。对于这个动作,你的 reducer 代码是什么样的?
标签: reactjs redux react-redux redux-saga reselect