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.