You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否合并Redux Toolkit ListenerMiddleware的状态与Action监听?

合并Redux Toolkit监听器:同时监听状态变更与Action完成

我需要触发同一个函数temperatureAlertEffect两次:一次在特定Redux状态变更后,一次在createPatchRecord.fulfilled Action执行完成后。目前用两个独立监听器可以正常运行,但尝试将predicate和actionCreator合并到同一个监听器时失败了,想知道正确的合并方式。

当前可正常运行的实现

export const addTemperatureAlertListener2 = (
  startListening: AppStartListening
) => {
  startListening({
    predicate: (action, currentState, originalState) => {
      return (
        currentState.chart.yLimits.yMax !== originalState.chart.yLimits.yMax ||
        currentState.chart.yLimits.yMin !== originalState.chart.yLimits.yMin ||
        currentState.user.tConfig.alertHigherThreshold !==
          originalState.user.tConfig.alertHigherThreshold
      );
    },
    effect: (action, listenerApi) => {
      temperatureAlertEffect(action, listenerApi);
    },
  });
};

export const addTemperatureAlertListener1 = (
  startListening: AppStartListening
) => {
  startListening({
    actionCreator: createPatchRecord.fulfilled,
    effect: (action, listenerApi) => {
      temperatureAlertEffect(action, listenerApi);
    },
  });
};

尝试但未成功的实现

export const addTemperatureAlertListener = (
  startListening: AppStartListening
) => {
  startListening({
    actionCreator: createPatchRecord.fulfilled,
    predicate: (action, currentState, originalState) => {
      return (
        currentState.chart.yLimits.yMax !== originalState.chart.yLimits.yMax ||
        currentState.chart.yLimits.yMin !== originalState.chart.yLimits.yMin ||
        currentState.user.tConfig.alertHigherThreshold !==
          originalState.user.tConfig.alertHigherThreshold
      );
    },
    effect: (action, listenerApi) => {
      temperatureAlertEffect(action, listenerApi);
    },
  });
};

问题原因与解决方案

你之前的合并写法失败,是因为Redux Toolkit的监听器规则:同时指定actionCreator和predicate时,必须两个条件同时满足才会触发——只有当触发的是createPatchRecord.fulfilled Action,且状态符合predicate的变更条件时,才会执行effect。但你的需求是任一条件满足就触发:要么状态发生指定变更(不管是什么Action导致的),要么createPatchRecord.fulfilled执行完成(不管状态有没有变化)。

正确的合并方式是去掉actionCreator,在predicate里同时判断两个条件,只要任一条件成立就返回true:

export const addTemperatureAlertListener = (
  startListening: AppStartListening
) => {
  startListening({
    predicate: (action, currentState, originalState) => {
      // 条件1:触发的是目标Action
      const isTargetAction = action.type === createPatchRecord.fulfilled.type;
      // 条件2:指定状态字段发生变更
      const isStateChanged = 
        currentState.chart.yLimits.yMax !== originalState.chart.yLimits.yMax ||
        currentState.chart.yLimits.yMin !== originalState.chart.yLimits.yMin ||
        currentState.user.tConfig.alertHigherThreshold !== originalState.user.tConfig.alertHigherThreshold;
      // 任一条件满足则触发effect
      return isTargetAction || isStateChanged;
    },
    effect: (action, listenerApi) => {
      temperatureAlertEffect(action, listenerApi);
    },
  });
};

这段代码完全等价于之前两个独立监听器的效果:不管是createPatchRecord.fulfilled执行完成,还是指定的状态字段发生变更,都会触发temperatureAlertEffect。

内容的提问来源于stack exchange,提问作者Jakob Maierhofer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 11:10:28