..are effing cool!
I've been using Recoil.js for a while now, but I've never taken the time to dive into atom effects before recently.
Why did I do so? Because I needed a timer. Or a clock if you will. Running in recoil. And atom effects seems to do the trick. Just look here
import {AtomEffect, atomFamily} from 'recoil';
export type Millisecounds = number;
const getUnixNow = () => Math.floor(Date.now() / 1000);
const clockEffect =
(interval: Millisecounds): AtomEffect<number> =>
({setSelf, trigger}) => {
if (trigger === 'get') {
setSelf(getUnixNow());
}
const timer = setInterval(() => setSelf(getUnixNow()), interval);
return () => clearInterval(timer);
};
/**
* Atom that contains the current unix timestamp
* Updates at the provided interval
*/
export const clockState = atomFamily<number, Millisecounds>({
key: 'clockState',
default: getUnixNow(),
effects: (interval: Millisecounds) => [clockEffect(interval)],
});
This gives you an atomFamiliy that can be instantiated with the desired interval, and this atom automagically updates each interval, in this case returning the current unix timestamp
const time = useRecoilValue(clockState(1000)); //new clock state that updates every secound
return <div>The current Unix time is now: {time}</div>
Neat?
Well. But what you can do is use this as a trigger in a selector that needs to run periodically
export const pollerState = selector<SomeData[]>({
key: 'pollerState ',
get: async ({get}) => {
//add this to referesh every minute
get(clockState(60000));
return await myApi.getSomeData();
},
});
And this is pretty neat!
And if this doesn't get you hooked on atom effects, take a look at this, straight outta the recoil docs (Just some TypeScript added):
export const localStorageEffect =
<T>(key: string): AtomEffect<T> =>
({setSelf, onSet}) => {
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
onSet((newValue, _, isReset) => {
isReset ? localStorage.removeItem(key) : localStorage.setItem(key, JSON.stringify(newValue));
});
};
const syncedState = atom<string>({
key: 'syncedState',
default: '',
effects: [localStorageEffect('local_storage_key')],
});
This actually syncs your atom to local storage. Sweet!
Top comments (0)