I really like the API of React's useMemo hook, where you write a function and list its dependencies in an array:
const memoizedValue = useMemo(
() => computeExpensiveValue(a, b),
[a, b]
);
It has the downside, however, that it can only be used inside a React function component. How can I implement something with the same API that can be used anywhere?
(Clarification)
I understand what memoization is. I'm talking specifically about the useMemo
hook's API. Whereas most memoization libraries take a function and return a memoized version of that function, useMemo
takes a function and an arguments list and returns a value. There are no wrapped functions exposed to the user.
The other interesting part of this API is that repeated calls to useMemo
will use the same cache, even though a new anonymous function is being created on every call (full example on codepen):
import {useMemo} from 'react';
import ReactDOM from 'react-dom';
function computeExpensiveValue(a, b) {
console.log('computing expensive value');
return a + b;
}
function MyComponent(props) {
const {a, b} = props;
const memoizedValue = useMemo(
() => computeExpensiveValue(a, b),
[a, b]
);
return <div>{memoizedValue}</div>
}
for (const i of [1, 2, 3]) {
ReactDOM.render(<MyComponent a={1} b={2} />, el);
}
This only logs "computing expensive value" once, even though three different functions are passed to useMemo
. Clearly useMemo
is using something other than the function object as its cache key, and that's the truly interesting part of its API.