If the dependency of the atom being get by useAtomCallBack(write-only atom) is changed, that atom will be read. #2789
-
Bug DescriptionAtoms not used in components are readI thought it would not read for the following reasons, but it does
Even though read-only atom (fetchAtom) is used only with useAtomCallBack When “userConfigTime” is used in a component, fetchAtom is read.
NOTEIf you change a dependency without ever updating it, fetchAtom is not read.
Instead of userConfigTime in fetchAtom Get (uncomment) wrapUserConfigTime. If the dependency is updated after this, wrapUserConfigTime is read instead of fetchAtom.
Inference from the aboveIt is likely that atom has been read in the following conditions.
Reproduction Link |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 15 replies
-
jotai/src/react/utils/useAtomCallback.ts Line 16 in 62c4892 useAtomCallback shouldn't subscribe to an atom. |
Beta Was this translation helpful? Give feedback.
-
Your understanding of the behavior of Here’s a more detailed explanation: Key Observations
Why Dependencies Are Added in SubtreesThe key lies in the shared mechanism used internally to evaluate dependencies. When
Example atom dependency treeConsider the following code: const store = createStore()
const a = atom(null, (get, set) => {
set(a, get(b))
})
let bReadCount = 0
const b = atom((get) => {
++bReadCount
return get(a) + 1
})
const c = atom((get) => get(b))
store.sub(c, () => {})
store.set(a)
expect(bReadCount).toBe(1)
store.set(c, 2)
expect(bReadCount).toBe(1) // fails: received 2 The dependency tree accessed by A.write's getter is as follows:
If
Summary of Behavior
Why is this behavior necessary?Let us again consider the sample code from earlier: const store = createStore()
const a = atom(null, (get, set) => {
set(a, get(b))
})
const b = atom((get) => {
return get(a) + 1
})
const c = atom(0)
store.sub(c, () => {})
store.set(a)
expect(store.get(c)).toBe(1)
store.set(a)
expect(store.get(c)).toBe(2) // otherwise would fail if write's get acted as peek If write's get does not update b's dependencies, then |
Beta Was this translation helpful? Give feedback.
-
@dai-shi If it is not used in a component, I would expect it to not be read if the dependency is changed. fetch atom being read
wrapUserConfigTime is read instead of fetchAtom.
|
Beta Was this translation helpful? Give feedback.
Your understanding of the behavior of
useAtomCallback
and the internal workings of Jotai is largely correct, but the distinction you’ve noted betweenatom.read
andatom.write
deserves some clarification, particularly regarding dependency tracking within the context ofwrite
operations.Here’s a more detailed explanation:
Key Observations
atom.read
Behavior:get
function inatom.read
is designed to track dependencies. When you callget(atom)
within anatom.read
function, Jotai automatically adds the accessedatom
to the dependency list of the current atom. This enables reactivity: changes to any of the dependencies trigger a re-evaluation of the atom.atom.write
Behavior:get
…