我真的很喜欢React的useMemo hook的API,您可以在其中编写一个函数并在数组中列出其依赖项:
id partner met id1 id2 id3 id4 id5 id6 id7 id8 id9 id10
id1 id10 1 NA NA NA NA NA NA NA NA NA 1
id2 id6 0 NA NA NA NA NA 0 NA NA NA NA
id3 id7 0 NA NA NA NA NA NA 0 NA NA NA
id4 id9 1 NA NA NA NA NA NA NA NA 1 NA
id5 id8 1 NA NA NA NA NA NA NA 1 NA NA
id6 NA NA NA NA NA NA NA NA NA NA NA NA
id7 NA NA NA NA NA NA NA NA NA NA NA NA
id8 NA NA NA NA NA NA NA NA NA NA NA NA
id9 NA NA NA NA NA NA NA NA NA NA NA NA
id10 NA NA NA NA NA NA NA NA NA NA NA NA
但是它有一个缺点,那就是只能在React函数组件中使用。如何使用可以在任何地方使用的相同API来实现某些东西?
(澄清)
我了解记忆是什么。我在专门谈论const memoizedValue = useMemo(
() => computeExpensiveValue(a, b),
[a, b]
);
钩子的API。多数记忆库都接受一个函数并返回该函数的记忆版本,而useMemo
接受一个函数和参数列表并返回 value 。没有向用户公开的包装函数。
该API另一个有趣的部分是,即使每次调用都创建了一个新的匿名函数(在codepen上的完整示例),对useMemo
的重复调用也将使用相同的缓存: / p>
useMemo
即使将三个不同的函数传递给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);
}
,这也只会记录一次“计算昂贵的价值”。显然,useMemo
使用的不是函数对象,而是缓存对象,这是其API真正有趣的部分。
答案 0 :(得分:0)
这个概念叫做备忘录,它有很多用javascript实现的方法,这里是一种流行的https://github.com/medikoo/memoizee#readme。
这是useMemo相同api的幼稚实现
const memorizedResults = new Map();
const useMemo = (fn, deps) => {
// there are two unique factors to the computation, first the function itself then the dependencies
// First memorize results based on FN
const memorizedResultsBasedOnFn =
memorizedResults.get(fn) ||
(memorizedResults.set(fn, new Map()) && memorizedResults.get(fn));
// Then get/set results based on dependencies to each individual function
return (
memorizedResultsBasedOnFn.get(deps) ||
(memorizedResultsBasedOnFn.set(deps, fn()) &&
memorizedResultsBasedOnFn.get(deps))
);
};
const someExpensiveComputation = n => {
console.log('n', n);
return n;
};
const f = () => someExpensiveComputation(10);
const anotherF = () => someExpensiveComputation(20);
const deps = [5];
const result1 = useMemo(f, deps); // These two will log n only once, meaning that f was called only once
const result2 = useMemo(f, deps);
const result3 = useMemo(f, [3]);
const result4 = useMemo(anotherF, deps);
// as expected will be 10 10 10 20 and 10 will be logged only twice
console.log(result1, result2, result3, result4);
在实际的实现中,您将使用WeakMap而不是Map,并且需要确保无论调用useMemo多少次,缓存的大小都不会无限期增加。