Re-execute atom whenever a component is mount #97
-
Below there's an atom that fetches data from a given URL. It's instantiated in a modal and executed on component mount. Example: const fetchSomethingAtom = atom(
'fetchSomethingAtom',
(componentId: string) => {
const queryApi = injectPromise(() => {
return fetch('some-url')
.then((response) => {
return response.json();
})
});
},
{
ttl: 0
}
);
// Using it later in a React component
const { data } = useAtomValue(fetchSomethingAtom);
// And here is some form logic to update some data, which we expect
// to retrieve when the modal is open. The problem is it's executed ONCE - meaning it's not executed when the modal is destroyed and then reopened. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hey @Darksoulsong as you have it, I'd expect
If other components, atoms, or selectors use the If the component doesn't actually unmount, its own Either way, you can always force the atom to reevaluate by invalidating it. For example, in a function MyModal({ id, open }) {
const fetchSomethingInstance = useAtomInstance(fetchSomethingAtom, [id])
const { data } = useAtomValue(fetchSomethingInstance)
useEffect(() => {
// just an example check to prevent double-fetching when the data hasn't loaded at all yet
if (open && data) {
fetchSomethingInstance.invalidate()
}
}, [open]) // only run when open
...
} Combine this with const fetchSomethingAtom = atom('fetchSomethingAtom', (componentId: string) => {
const queryApi = injectPromise(
() => {
return fetch('some-url').then((response) => {
return response.json();
});
},
[],
{ runOnInvalidate: true }
);
return queryApi.setTtl(0);
}); I don't think I've ever used this pattern - it should usually be unnecessary. But it's there if you need it. Still, if possible I recommend ensuring that all dependents die on modal unmount so that If nothing is holding onto the atom instance when the modal closes but the atom still doesn't re-initialize, that sounds like a bug. A codesandbox reproing it would be helpful for triage. |
Beta Was this translation helpful? Give feedback.
Hey @Darksoulsong as you have it, I'd expect
ttl: 0
to do the trick. But there are a few more factors to consider:null
when itsopen
prop is false)?If other components, atoms, or selectors use the
fetchSomethingAtom
, they may be preventing it from being destroyed. When the modal is closed, you can check the atom's dependents withecosystem.viewGraph()
to see if it's still in the graph and what dependents are keeping it there.If the component doesn't actually unmount, its own
useAtomValue
call will maintain the dependency on the atom, preve…