Skip to content

Instantly share code, notes, and snippets.

@NoriSte
Created October 20, 2020 05:52
Show Gist options
  • Save NoriSte/bd57eebfb13ac859702c04803c09cd7c to your computer and use it in GitHub Desktop.
Save NoriSte/bd57eebfb13ac859702c04803c09cd7c to your computer and use it in GitHub Desktop.
Re-implementing Recoil APIs / article gists
// @see https://github.com/NoriSte/recoil-apis
type Callback = () => void;
/**
* Subscribe/unsubscribe to all the updates of the involved Recoil Values
*/
const useSubscribeToRecoilValues = <T>(
recoilValue: RecoilValue<T>,
callback: Callback
) => {
const recoilId = useRecoilId();
useEffect(() => {
if (isAtom(recoilValue)) {
return subscribeToRecoilValueUpdates(recoilId, recoilValue.key, callback);
} else {
const dependencies: string[] = [];
recoilValue.get({ get: createDependenciesSpy(recoilId, dependencies) });
const unsubscribes: Callback[] = [];
dependencies.forEach((key) =>
unsubscribes.push(
subscribeToRecoilValueUpdates(recoilId, key, callback)
)
);
return () => unsubscribes.forEach((unsubscribe) => unsubscribe());
}
}, [recoilId, recoilValue, callback]);
};
/**
* Figure out the dependencies tree of each selector.
* Please note: it doesn't support condition-based dependencies tree.
*/
const createDependenciesSpy = (recoilId: string, dependencies: string[]) => {
const dependenciesSpy = (recoilValue: RecoilValue<any>) => {
dependencies.push(recoilValue.key);
if (isAtom(recoilValue)) {
return coreGetRecoilValue(recoilId, recoilValue);
} else {
return recoilValue.get({ get: dependenciesSpy });
}
};
return dependenciesSpy;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment