I'm using Recoil (recoiljs.org) in my react project.
I have a fairly classic setup with a list of items - the object graph looks something like this:
Routes - routes is an array of Route objects
- Route - route object is edited in a form
I use an atom to represent the currently selected Routes array, e.g.
const [routes, setRoutes] = useRecoilValue(currentRoutesViewState);
And I also use a selectorFamily
to allow individual controls to bind to and update the state of an individual item.
const routeSelectorFamily = selectorFamily({
key: "routeSelectorFamily",
get:
(routeKey) =>
({ get }) => {
const routes = get(currentRoutesViewState);
return routes.find((r) => r.key === routeKey);
},
set:
(routeKey) =>
({ set }, newValue) => {
set(currentRoutesViewState, (oldRoutes) => {
const index = oldRoutes.findIndex((r) => r.key === routeKey);
const newRoutes = replaceItemAtIndex(
oldRoutes,
index,
newValue as RouteViewModel
);
return newRoutes;
});
},
});
As you can see, the set
function allows someone to update an individual route state and that is replicated up into anything rendering routes.
However, I would like to auto-save any changes to this whole graph but don't know how to easily observe any changes to the Routes parent object. Is there a way to programmatically subscribe to updates so I can serialize and save this state?
You can just use a useEffect
for that:
const currentState = useRecoilValue(currentRoutesViewState);
useEffect(() => {
// currentState changed.
// save the current state
}, [currentState])