I was wondering if we could get some detail about how/when things get removed from Recoil's internal cache. Does Recoil have internal reference counting? I see some code about persistence, but it's hard to follow without any context.
There's also the recommendation to use a memoize function like the itemWithId example from the React Europe talk. Is Recoil going to have a memoization mechanism? Otherwise, how should we manage when to remove things from our memoization cache?
Hi @jamiebuilds There is some information about this in https://github.com/facebookexperimental/Recoil/issues/30#issuecomment-629388549 and https://github.com/facebookexperimental/Recoil/issues/23#issuecomment-629361255
We are adding a feature soon where atoms will be deleted when no longer used, together with another hook that lets a component retain an atom without subscribing to it. These could be combined into a utility that gives you a list of IDs with automatic deletion of the individual atoms when they are removed from the list.
Currently you have to use the useResetRecoilState hook to delete atoms.
To make a family of atoms, just create a memoized function that returns a distinct atom for each state
[snip]
We are going to open-source a utility called atomFamily/selectorFamily that does this for you in the near future.
Sounds like selectorFamily has built in memoization. https://recoiljs.org/docs/api-reference/utils/selectorFamily
We are planning some memory management improvements where atomFamily and selectorFamily will forget when Recoil itself does. At the moment they are just simple implementations of memoization, equivalent to what you might do yourself. We plan to roll out better memory management soon.
Regarding this point, make sense to have a delete operation? Like we have the get/set/reset.
Follow me on my thought please:
Imagine we have an atom that is a list (todo for example), and we have an atomFamily that is an item on that list.
we could create a selector for our list like so:
const todoAtom = atom({
key: 'todoAtom',
default: []
});
const todoItemAtom = atomFamily({
key: 'todoItemAtom',
default: {
label: 'todo item',
completed: false
}
});
const todoState = selector({
key: 'todoState',
get: ({ get }) => get(todoAtom),
set({ get, set, delete }, { type, payload }) {
let todo = get(todoAtom);
switch(type) {
case ADD_ITEM:
todo = [...todo, uuid()];
break;
case REMOVE_ITEM:
todo.filter((id) => id !== payload.id);
delete(todoItemAtom(payload.id));
break;
default:
return;
}
set(todoAtom, todo);
}
});
鈽濓笍 make sense the delete? And, is this a "correct" approach for a list of items?
Thanks in advance and awesome work mates, being testing and it feels good :)
Most helpful comment
We are planning some memory management improvements where atomFamily and selectorFamily will forget when Recoil itself does. At the moment they are just simple implementations of memoization, equivalent to what you might do yourself. We plan to roll out better memory management soon.