react学习笔记8 useMemo

80 阅读2分钟

在 React 中,useMemo 是一个非常有用的 Hook,用于缓存函数的返回值,从而避免在每次渲染时都重新计算昂贵的运算结果。这对于提高性能非常有帮助,尤其是在函数的计算成本较高时。

在 TypeScript 中使用 useMemo 时,我们需要确保类型正确并且安全。下面是一些关于如何在 TypeScript 中使用 useMemo 的示例:

基础示例这个示例展示了如何使用 useMemo 来缓存一个昂贵的运算结果。

import React, { useMemo, useState } from 'react';  
  
function ExampleComponent() {  
const [number, setNumber] = useState(1);  
  
const expensiveComputation = useMemo(() => {  
// 模拟一个昂贵的运算  
for (let i = 0; i < 1000000000; i++) {  
/* ... */  
}  
return number * number;  
}, [number]); // 依赖数组只包含 number,这意味着每当 number 改变时都会重新执行这个 memoized function  
  
return (  
<div>  
<p>Number: {number}</p>  
<p>Expensive computation result: {expensiveComputation}</p>  
<button onClick={() => setNumber(number + 1)}>  
Increase number  
</button>  
</div>  
);  
}  
  
export default ExampleComponent;  

使用泛型当你需要在 useMemo 内部访问组件的 props 或其他类型时,你可以使用泛型来增强类型安全性。

 import React, { useMemo, useState } from 'react';  
  
interface Props {  
initialValue: number;  
}  
  
function ExampleComponent({ initialValue }: Props) {  
const [number, setNumber] = useState(initialValue);  
  
const expensiveComputation = useMemo(() => {  
// 模拟一个昂贵的运算  
for (let i = 0; i < 1000000000; i++) {  
/* ... */  
}  
return number * number;  
}, [number]); // 依赖数组只包含 number  
  
return (  
<div>  
<p>Number: {number}</p>  
<p>Expensive computation result: {expensiveComputation}</p>  
<button onClick={() => setNumber(number + 1)}>  
Increase number  
</button>  
</div>  
);  
}  
  
export default ExampleComponent;  

使用 TypeScript 的类型别名为了使你的代码更加清晰和易于维护,你可以使用类型别名来定义组件的 props 类型。

import React, { useMemo, useState } from 'react';  
  
type Props = {  
initialValue: number;  
};  
  
function ExampleComponent({ initialValue }: Props) {  
const [number, setNumber] = useState(initialValue);  
  
const expensiveComputation = useMemo(() => {  
// 模拟一个昂贵的运算  
for (let i = 0; i < 1000000000; i++) {  
/* ... */  
}  
return number * number;  
}, [number]); // 依赖数组只包含 number  
  
return (  
<div>  
<p>Number: {number}</p>  
<p>Expensive computation result: {expensiveComputation}</p>  
<button onClick={() => setNumber(number + 1)}>  
Increase number  
</button>  
</div>  
);  
}  
  
export default ExampleComponent;  

使用 useMemo 与外部库结合假设你正在使用一个外部库,例如 lodash,来处理数据。你可以结合使用 useMemo 来缓存计算结果。

import React, { useMemo, useState } from 'react';  
import _ from 'lodash';  
  
function ExampleComponent() {  
const [number, setNumber] = useState(1);  
  
const expensiveComputation = useMemo(() => {  
// 使用 lodash 的 mapValues 方法来模拟一个昂贵的运算  
return _.mapValues({ key: number }, (value) => value * value);  
}, [number]); // 依赖数组只包含 number  
  
return (  
<div>  
<p>Number: {number}</p>  
<p>Expensive computation result: {JSON.stringify(expensiveComputation)}</p>  
<button onClick={() => setNumber(number + 1)}>  
Increase number  
</button>  
</div>  
);  
}  
  
export default ExampleComponent; 

使用 useMemo 与 useCallbackuseMemo 和 useCallback 经常一起使用。useCallback 用于缓存函数,而 useMemo 用于缓存值。

import React, { useCallback, useMemo, useState } from 'react';  
  
function ExampleComponent() {  
const [number, setNumber] = useState(1);  
  
const expensiveComputation = useMemo(() => {  
// 模拟一个昂贵的运算  
for (let i = 0; i < 1000000000; i++) {  
/* ... */  
}  
return number * number;  
}, [number]);  
  
const handleIncrease = useCallback(() => {  
setNumber((prevNumber) => prevNumber + 1);  
}, []);  
  
return (  
<div>  
<p>Number: {number}</p>  
<p>Expensive computation result: {expensiveComputation}</p>  
<button onClick={handleIncrease}>  
Increase number  
</button>  
</div>  
);  
}  
  
export default ExampleComponent;