Consecutive updates prevent re-evaluation of derived atom in v2.11.0 #2916
-
Bug DescriptionIn Jotai v2.11.0, batch processing was introduced for atom re-evaluation. As a result, in some cases, certain derived atoms are not re-evaluated when an atom is updated. Below is a typical reproduction example. In this example, Under Jotai v2.10.4, // counter atom
const countAtom = atom(0);
// object atom with versioning
const objBaseAtom = atom({ value: 100 });
const objVersionAtom = atom(0);
const objAtom = atom((get) => {
console.log("eveluate objAtom");
get(objVersionAtom); // depend on version
return get(objBaseAtom);
});
const updateObjAction = atom(undefined, (get, set) => {
get(objBaseAtom).value++; // update object content
console.log("updateObjAction: increment objVersionAtom");
set(objVersionAtom, (c) => c + 1); // update version to cause re-evaluation
});
// action to update both counter and object
const updateCounterAndObjAction = atom(undefined, (get, set) => {
set(updateObjAction);
console.log("updateCounterAndObjAction: increment countAtom");
set(countAtom, (c) => c + 1);
});
// derived atom with both counter and object
const countAndObjAtom = atom((get) => {
console.log("eveluate countAndObjAtom");
const obj = get(objAtom);
const count = get(countAtom);
return { count, obj };
});
export const App = () => {
const { count, obj } = useAtomValue(countAndObjAtom);
const countDirect = useAtomValue(countAtom);
const update = useSetAtom(updateCounterAndObjAction);
return (
<div>
<h2>two count should be same</h2>
<p>count direct: {countDirect}</p>
<p>count derived: {count}</p>
<p>obj.value: {obj.value}</p>
<button type="button" onClick={update}>
Update
</button>
</div>
);
}; I do not fully understand the changes introduced in v2.11.0, but I suspect the following sequence of events:
Based on this assumption, here is the minimal reproduction code. This code also behaves normally under v2.10.4, but under v2.11.0, const atomA = atom(0);
const atomB = atom(0);
const atomC = atom((get) => {
get(atomA);
return 0;
});
const atomD = atom((get) => {
get(atomC);
return get(atomB);
});
const updateAtom = atom(undefined, (get, set) => {
set(atomA, (c) => c + 1);
set(atomB, (c) => c + 1);
});
export const App2 = () => {
const valB = useAtomValue(atomB);
const valD = useAtomValue(atomD);
const update = useSetAtom(updateAtom);
return (
<div>
<h2>val B should be same as val D</h2>
<div>val B: {valB}</div>
<div>val D: {valD}</div>
<button type="button" onClick={update}>
Update
</button>
</div>
);
}; I think this behavior is likely a bug, but I am unsure of the specific fix. Reproduction Link |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Not obvious, but looks to be a duplicate of #2906. PR: Codesandbox: |
Beta Was this translation helpful? Give feedback.
Not obvious, but looks to be a duplicate of #2906.
PR:
#2907
Codesandbox:
https://codesandbox.io/p/sandbox/jotai-v2-11-0-re-evaluation-bug-forked-c4hn45