I decided to try using recoil instead of redux and ran into the problem of caching mutable collections. To be more precise, the problem is not in the response caching itself, but in the further data management, without re-requesting. For example, I requested an array of free time slots that will be displayed in the calendar, the user can change them (unblock or block). After the request (unblock or block) I can use useRecoilRefresher_UNSTABLE to reset the selector cache and request updated slots again, this works as expected, but why do this if you can remember the result after the first request and then just update it. My code is:
export const _cacheFreeSlotsA = atom<SlotsArray | null>({
key: '_cacheFreeSlotsA',
default: null,
});
export const freeSlotsS = selector<SlotsArray>({
key: 'freeSlotsS',
get: async ({ get }) => {
const cache = get(_cacheFreeSlotsA);
if (cache) {
return cache;
}
const res = await slotsAPI.getFreeSlots();
return res.slots;
},
});
export const useUpdateFreeSlotsS = () => {
const setFreeSlots = useSetRecoilState(_cacheFreeSlotsA);
const currentSlots = useRecoilValue(freeSlotsS);
return async (req: ChangeSlotsRequest) => {
await slotsAPI.changeSlots(req);
switch (req.operation) {
case 'open':
setFreeSlots([...currentSlots, ...req.slots]);
break;
case 'close':
setFreeSlots(difference(currentSlots, req.slots));
break;
}
};
};
// export const useUpdateFreeSlotsS = () => {
// const refresh = useRecoilRefresher_UNSTABLE(freeSlotsS);
// return async (req: ChangeSlotsRequest) => {
// await slotsAPI.changeSlots(req);
// refresh();
// };
// };
It works but look like workaround. Is there a more elegant and clear way to implement this behavior? (it would be just perfect if inside the freeSlotsS get method I could get access to the set method, but unfortunately it is not in the arguments)