Open JavierM42 opened 2 years ago
https://github.com/facebookexperimental/Recoil/discussions/1785
I personally ended up using React Effect or useRecoilCallback with atomEffect. Not so intuitive way though.
1785
I personally ended up using React Effect or useRecoilCallback with atomEffect. Not so intuitive way though.
Hi tpAtalas
Could you please elaborate on your answer? I mean, how did you update state B as an effect of updating state A? You mention
using React Effect or useRecoilCallback with atomEffect
I'm updating the state inside a useRecoilCallback
but I don't see the possibility to attach an effect to it...
Would you be so kind to share a code example?
Hm maybe I would do something like this:
const atomOffline = atom({
key: 'atomWithAtomEffect',
default: false,
effects: [offlineEffect],
});
const atomAnother = atom({
key: 'atomAntoher',
default: false,
});
// Object: set atomAnother 'true' whenever atomOffline is set to true (becoming offline), triggered by offlineEffect.
// 1. Create effect component (or hook)
export const SyncAtomsEffects = () => {
// const offlineAtom = useRecoilValue(atomOffline)
// You need to use RecoilValue if you have not rendered this atom in any component.
// However, getting another atom within useRecoilcallback is always better since it will not trigger any re-rendering while you get the value.
const syncAtoms = useRecoilCallback(({ snapshot, set, reset }) => () => {
const get = <T,>(p: RecoilValue<T>) => snapshot.getLoadable(p).getValue();
if (get(atomOffline)) return set(atomAnother, true);
return reset(atomAnother);
});
useEffect(() => {
syncAtoms();
}, [syncAtoms]);
return null;
};
// 2. Insert SyncAtomEffect into another component, where you wanna trigger the sync
export const IamAComponent = () => {
return (
<>
<SyncAtomEffects />
<Layout>
<ComponentExampleA>
<ComponentExampleB />
</ComponentExampleA>
</Layout>
</>
);
};
I think the best part is this effect component will not trigger any re-rendering of the component
@tpatalas Thanks for this. I tried this out and while it works, if we are syncing 1 to many atoms - it breaks. For example, pull an atom/selector by list and reindex by id, then this will break in production. During test mode it works fine, but because it sets many atoms, this will cause a ton a refreshes/rerendering.
There has to be a better way to handle this... unfortunately this is a huge barrier since either i have to rewrite entire atom structure for list vs by id or have to switch to another library such as jotai
Is there a reason for the Atom Effect parameters not including
set
?My use case is I'd like to set another atom to update UI with the state of local updates.
Here's a very simple example: