我最终从各种答案中选取了一些来创建自己的hook。我希望能够仅通过替换 useEffect
来快速调试哪个依赖项会触发 useEffect
。
const usePrevious = (value, initialValue) => {
const ref = useRef(initialValue);
useEffect(() => {
ref.current = value;
});
return ref.current;
};
const useEffectDebugger = (effectHook, dependencies, dependencyNames = []) => {
const previousDeps = usePrevious(dependencies, []);
const changedDeps = dependencies.reduce((accum, dependency, index) => {
if (dependency !== previousDeps[index]) {
const keyName = dependencyNames[index] || index;
return {
...accum,
[keyName]: {
before: previousDeps[index],
after: dependency
}
};
}
return accum;
}, {});
if (Object.keys(changedDeps).length) {
console.log('[use-effect-debugger] ', changedDeps);
}
useEffect(effectHook, dependencies);
};
下面是两个例子。对于每个示例,我假设dep2
从“foo”更改为“bar”。示例1显示没有传递dependencyNames
的输出结果,示例2显示了一个使用了dependencyNames
参数的示例。
示例1
之前:
useEffect(() => {
}, [dep1, dep2])
之后:
useEffectDebugger(() => {
}, [dep1, dep2])
控制台输出:
{
1: {
before: 'foo',
after: 'bar'
}
}
对象键 '1' 表示发生更改的依赖项的索引。在这里,dep2
发生了更改,因为它是依赖项中的第二个项目,或索引1。
示例 2
之前:
useEffect(() => {
}, [dep1, dep2])
之后:
useEffectDebugger(() => {
}, [dep1, dep2], ['dep1', 'dep2'])
控制台输出:
{
dep2: {
before: 'foo',
after: 'bar'
}
}
useEffect
(每个独立可能发生变化的变量一个)是否有意义。因为很明显您正在尝试将两个用例合并成一个? - Archmede