let computeCount = 0;
function useMemo(factory, deps) {
let cached = null;
return function get(newDeps) {
// Bug: comparing arrays by reference — always different!
if (cached && cached.deps === newDeps) {
return cached.value;
}
computeCount++;
cached = { value: factory(), deps: newDeps };
return cached.value;
};
}
const getValue = useMemo(() => computeCount * 100, []);
getValue([1, 2]);
getValue([1, 2]);
getValue([1, 2]);
console.log(computeCount); // should be 1, is 3let computeCount = 0;
function useMemo(factory, deps) {
let cached = null;
return function get(newDeps) {
const isSame = cached &&
cached.deps.length === newDeps.length &&
cached.deps.every((d, i) => d === newDeps[i]); // element-by-element
if (isSame) {
return cached.value;
}
computeCount++;
cached = { value: factory(), deps: newDeps };
return cached.value;
};
}
const getValue = useMemo(() => computeCount * 100, []);
getValue([1, 2]);
getValue([1, 2]);
getValue([1, 2]);
console.log(computeCount);Bug: cached.deps === newDeps compares array references. [1,2] === [1,2] is false (different objects). Cache never hits, recomputes every call.
Explanation: Element-by-element comparison: same length and all elements ===. New [1,2] arrays have the same content, so cache hits on the 2nd and 3rd calls.
Key Insight: React compares deps shallowly — each element with ===, not the array reference. Two different [1,2] arrays are considered 'same deps'. This is why primitive deps work but object deps don't.