Skip to content

Instantly share code, notes, and snippets.

@amanda-mitchell
Last active February 11, 2019 00:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amanda-mitchell/a9f9586aff7dd8b63b02ec2a1e868bf7 to your computer and use it in GitHub Desktop.
Save amanda-mitchell/a9f9586aff7dd8b63b02ec2a1e868bf7 to your computer and use it in GitHub Desktop.
function useBoundEffect<TArguments extends any[]>(
effect: (...params: TArguments) => ReturnType<React.EffectCallback>,
getArguments: () => TArguments
) {
const lastArguments = useRef<TArguments | undefined>(undefined);
const lastEffectCleanup = useRef<ReturnType<React.EffectCallback>>(undefined);
useEffect(() => {
const newArguments = getArguments();
if (areEquivalent(lastArguments.current, newArguments)) {
return;
}
lastArguments.current = newArguments;
if (lastEffectCleanup.current) {
lastEffectCleanup.current();
}
lastEffectCleanup.current = effect(...newArguments);
});
useEffect(() => {
return () => {
if (lastEffectCleanup.current) {
lastEffectCleanup.current();
}
};
}, []);
}
function areEquivalent<TArguments extends any[]>(
left: TArguments | undefined,
right: TArguments | undefined
) {
if (!left) {
return !right;
}
if (!right) {
return false;
}
const { length } = left;
if (length !== right.length) {
return false;
}
for (let index = 0; index < length; ++index) {
if (left[index] !== right[index]) {
return false;
}
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment