What's the significance of `secondaryDeps`?
Hi, I've read the 2 articles written by you, nice articles. But I have some doubts about useGranularEffect:
function useGranularEffect(effect, primaryDeps, secondaryDeps){
const ref = useRef();
if (!ref.current || !primaryDeps.every((d, i) => Object.is(d, ref.current[i]))) {
ref.current = [...primaryDeps, ...secondaryDeps];
}
return useEffect(effect, ref.current);
};
The effect will execute only when any item of primaryDeps changes. So what's the significance of secondaryDeps? I think the secondaryDeps could always be an empty array [], and even does not need to exist.
Actually, maybe the 2 code blocks are identical:
useGranularEffect(() => {
setData(value + other);
}, [value], [other]);
with
useEffect(() => {
setData(value + other);
}, [value]);
The only difference is that ESLint will throw a warning at the dependencies array of useEffect at the second one, but ESLint will also throw the warning at the implementation of useGranularEffect, the useEffect called by useGranularEffect.
The goal of the secondaryDeps for any of the granular hooks is to show intent. Like you said, the end result is the same as passing an empty array. But an empty array is ambiguous: was the dependency forgotten, or is it simply not necessary?
Listing all the dependencies in their appropriate array shows clear intent as to when we want to hook to be run.
If working with eslint-plugin-react-hooks/exhaustive-deps, it is indeed annoying that the warning triggers, since it forces us to disable the rule and therefore moving us back to the ambiguity issue. If you want to go through the trouble of creating your own custom rules, I adapted the original rule for granular-hooks here.