Skip to content

Instantly share code, notes, and snippets.

@tannerlinsley
Created August 28, 2020 23:45
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tannerlinsley/a1c7e118164b0a1e2c14d2952b9248fb to your computer and use it in GitHub Desktop.
Save tannerlinsley/a1c7e118164b0a1e2c14d2952b9248fb to your computer and use it in GitHub Desktop.
useGlobalMemo is a React hook that lets you share memoizations across an entire app using a unique key.
const cache = {}
export default function useGlobalMemo (key, fn, deps) {
if (!cache[key]) {
cache[key] = {
subs: 0,
deps,
value: fn(),
}
} else {
const oldDeps = cache[key].deps
if (oldDeps.length !== deps || oldDeps.some((d, i) => deps[i] !== d)) {
cache[key] = {
deps,
value: fn()
}
}
}
React.useEffect(() => {
cache[key].subs += 1
return () => {
cache[key].subs -= 1
if (!cache[key].subs) {
delete cache[key]
}
}
}, [])
return cache[key].value
}
@wolverineks
Copy link

@14, should that be oldDeps.length !== deps.length?

@tannerlinsley
Copy link
Author

Yep lol

@AjaxSolutions
Copy link

AjaxSolutions commented Aug 29, 2020

Looks good! Is this code by any chance mimicked after the Recoil library? I think they have something similar.

@a-eid
Copy link

a-eid commented Oct 14, 2020

what are the use cases for a useGlobalMemo ?

@a-eid
Copy link

a-eid commented Oct 15, 2020

there is a possible issue with deps, it would probably be better to replace deps with a revision or a version key ( string | number ).

the hook could also return a method to reset the cached method as well.

  const { value: fn, changeCachedValue } = useGlobalMemo('key',() => veryExpensiveFunction(0), 0);
  changeCachedValue(() => veryExpensiveFunction(1));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment