If I use Atom on a mounted component, how can I avoid multiple reads when dependencies are updated? #2782
-
Hi step
another idea(No Tried) Tried and tested code import { atom , useAtom , useAtomValue , useSetAtom} from "jotai";
import { atomWithDefault , atomWithRefresh , RESET, useAtomCallback } from "jotai/utils";
import { useCallback } from "react";
const baseCount1 = atom(0);
const baseCount2 = atom(0);
const readCountAtom = atom((get) => {
// console.log('readCountAtom:read');
return get(baseCount1) + get(baseCount2);
})
const wrapReadCountDefault = atom((get) => {
// console.log('wrapReadCountDefault:read');
return get(readCountDefault);
});
const readCountDefault = atomWithDefault((get) => {
console.log("readCountDefault:read");
return get(baseCount1) + get(baseCount2);
});
const readCountRefresh = atomWithRefresh((get) => {
// console.log("readCountRefresh:read")
return get(baseCount1) + get(baseCount2);
});
function MountReadAtom() {
const [countRefresh, setRefresh] = useAtom(readCountRefresh);
const [countDefault, setReset] = useAtom(readCountDefault);
const wrapCountDefault = useAtomValue(wrapReadCountDefault);
const countAtom = useAtomValue(readCountAtom);
const setCount1 = useSetAtom(baseCount1);
const setCount2 = useSetAtom(baseCount2);
// Read multiple times
const handleRefresh = useCallback(() => {
setCount1((prev) => prev + 1);
setCount2((prev) => prev + 1);
setRefresh();
}, [setCount1, setCount2, setRefresh]);
// Read once
const handleDefault = useCallback(() => {
setReset(0);
setCount1((prev) => prev + 1);
setCount2((prev) => prev + 1);
setReset(RESET);
}, [setCount1, setCount2, setReset]);
// Read multiple times
const handleCountAtom = useCallback(() => {
setCount1((prev) => prev + 1);
setCount2((prev) => prev + 1);
},[setCount1, setCount2])
// Read once
const handleDefaultAtomCallBack = useAtomCallback(
useCallback(() => {
setReset(0);
setCount1((prev) => prev + 1);
setCount2((prev) => prev + 1);
setReset(RESET);
}, [setCount1, setCount2, setReset])
);
return (
<>
<button onClick={handleRefresh}>Refresh: {countRefresh}</button>
<button onClick={handleDefault}>Default: {countDefault}</button>
<button onClick={handleCountAtom}>commonAtom: {countAtom}</button>
<button onClick={handleDefaultAtomCallBack}>
handleDefaultAtomCallBack
</button>
<label>WrapDefault: {wrapCountDefault}</label>
</>
);
}
export default MountReadAtom; |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 12 replies
-
I'm not sure if I follow 100%, but can you define a write-only atom to prevent it? |
Beta Was this translation helpful? Give feedback.
-
There are several read-only atoms that communicate with the backend. They use multiple common atoms (dependencies) for fetching data. For example: export const fetch1 = atom(async (get) => {
const atomData1 = await get(atom1);
const atomData2 = await get(atom2);
return await fetchData1(atomData1, atomData2);
});
export const fetch2 = atom(async (get) => {
const atomData1 = await get(atom1);
const atomData2 = await get(atom2);
return await fetchData2(atomData1, atomData2);
}); It’s very convenient that updating When If there are cases where an atom is read multiple times and others where it’s not, please let me know.🙇♂️ |
Beta Was this translation helpful? Give feedback.
In Jotai,
set
recomputes the dependents of an atom in place. This ensures that if those values are accessed in the very next line usingget
, they reflect the updated state. Consider the following example:This behavior means that every time an atom's value is updated with
set
, all its dependents are recalculated, even if they aren't accessed in the write function.Edit: I am exploring changing this behavior so that only the dependents accessed with
get
will be recomputed in place, al…