检测到 Redux 状态未发生变化时反应 useMemo 触发

时间:2021-05-18 11:47:23

标签: reactjs redux

我在 Redux 中有一个状态对象,并且正在使用 useSelector 和 deepEqual(来自 fast-deep-equal)来检测更改。然后在当前状态上使用备忘录。令人费解的是,尽管状态似乎没有改变,但 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! 也会输出。

谢谢

0 个答案:

没有答案