首页 > 解决方案 > 当检测到 Redux 状态没有变化时响应 useMemo 触发

问题描述

我在 Redux 中有一个状态对象,并且正在使用 useSelector 和 deepEqual(来自 fast-deep-equal)来检测更改。然后在当前状态上使用Memo。令人费解的是,即使状态似乎没有改变,useMemo 也被调用了。

这是我的代码的结构:

import deepEqual from "fast-deep-equal"

export function useMyState() {
    const values = useSelector(
        (store) => store.prop1,
        (a, b) => { // comparison function arg to useSelector
            const equal = deepEqual(a, b)
            if (!equal) {
                console.log("COMPARE FALSE")
            }
            return equal
        }
    )
    useEffect(() => {
        console.log("MOUNTED")
    }, [])

    return useMemo(() => {
        console.log("VALUES CHANGED", JSON.stringify(values))
        return {
            values,
            method1() {
                // do something
            }
        }
    }, [values])
}

我确认MOUNTED只输出一次,VALUES CHANGED即使COMPARE FALSE不输出也是输出。怎么会这样...?

也许如果组件恰好被渲染为父渲染的一部分,它总是从存储中获取当前对象(这不是===以前的值)并且useSelector比较 fn 仅用于在状态没有时防止组件的重新渲染(隔离)改变了吗?useMemo如果是这种情况,当值深度相等时,防止运行的最佳实践方法是什么?

代码沙盒: https ://codesandbox.io/s/redux-state-change-zdxzs

当有两个useSelector和一个被触发时会出现此问题,从而导致重新渲染。然后组件认为另一个的结果useSelector已经改变,即使它没有根据选择器本身的测试(deepEqual)。

要重现上述链接,请单击增量按钮几次 - 组件已呈现但未更改待办事项。然后单击“重新创建”按钮并再次递增。即使项目没有根据deepEqual文本改变,TODOS CHANGED!也会输出。

谢谢

标签: reactjsredux

解决方案


推荐阅读