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

reselect createSelector与memoizeOptions使用异常:自定义对比未生效

问题排查与解决

核心原因:对reselect缓存逻辑的误解 + 配置参数名错误

1. 缓存逻辑的本质误解

createSelector默认使用memoizeOne对整个选择器的输入参数进行缓存,而非输入选择器的返回值。你两次调用select(state0, 2)时,传入的state0是同一个对象引用,index都是2,所以memoizeOne判定参数未变化,直接返回缓存结果,根本不会触发输入选择器和结果函数的重新执行,因此recomputations()始终为1。

2. 配置参数名错误

你在memoizeOptions中使用的equalityCheck和resultEqualityCheck不是memoizeOne的合法参数名,正确的参数名是equalityFn,用于比较选择器的输入参数是否相同。这导致你的自定义比较逻辑完全未生效。

修复方案

方案一:修改memoizeOptions参数,强制每次调用都重新计算

将memoizeOptions中的参数名改为equalityFn,并让它始终返回false,这样无论参数是否相同,都会触发重新计算:

const select = createSelector(
    (state, index: number): number[] => state.a.slice(0, index),
    (state, index: number): string[] => state.b.slice(0, index),
    (a_in: number[], b_in: string[]): (number | string)[] => [...a_in, ...b_in],
    { 
        memoizeOptions: { 
            equalityFn: () => false // 强制认为参数不同,每次都重新计算
        } 
    }
);

方案二:基于输入选择器的结果判断是否重新计算

如果你希望根据输入选择器的返回值(而非选择器参数)来决定是否重新计算,需要使用createSelectorCreator自定义选择器的缓存逻辑,替换默认的参数比较为输入结果比较:

import { createSelectorCreator, defaultMemoize } from "reselect";

// 自定义选择器创建器,基于输入选择器的结果进行缓存判断
const createSelectorByInputResults = createSelectorCreator(
    defaultMemoize,
    // 比较两次调用的输入选择器结果数组是否相同
    (prevInputs, currInputs) => {
        return prevInputs.every((prev, idx) => prev === currInputs[idx]);
    }
);

// 使用自定义创建器构建选择器
const select = createSelectorByInputResults(
    (state, index: number): number[] => state.a.slice(0, index),
    (state, index: number): string[] => state.b.slice(0, index),
    (a_in: number[], b_in: string[]): (number | string)[] => [...a_in, ...b_in]
);

此时,因为两次调用输入选择器返回的是不同引用的数组,prev === curr会返回false,因此会触发重新计算,recomputations()会变为2。

验证结果

修改后重新运行测试,第二次调用select(state0,2)时,recomputations()的值会变为2,符合你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:15:39