上述代码中,useSate
用于定义了三个状态:supNum
、oppNum
、x
。在组件函数中,我们根据这些状态来计算投票的支持率,并将其渲染到视图中。但是,每次状态变化时,投票支持率的计算都会重新执行,即使其他状态(比如 x
)的变化并不影响支持率的计算。
为了更好地优化性能,我们可以使用 useMemo
钩子在支持人数或反对人数发生变化时,重新计算投票支持率。例如,可以这样重构代码:
import React, { useState, useMemo } from "react";
import { Button } from 'antd';
import './Demo.less';
const Demo = () => {
const [supNum, setSupNum] = useState(10);
const [oppNum, setOppNum] = useState(5);
const [x, setX] = useState(0);
const ratio = useMemo(() => {
const total = supNum + oppNum;
return total > 0 ? ( supNum / total * 100).toFixed(2) + '%' : '--';
}, [supNum, oppNum]);
return (
<div className="vote-box">
<div className="main">
<p>支持人数:{supNum}人</p>
<p>反对人数: {oppNum}人</p>
<p>支持比率: {ratio}</p>
<p>x:{x}</p>
</div>
<div className="footer">
<Button type="primary" onClick={() => setSupNum(supNum + 1)}>支持</Button>
<Button type="primary" danger onClick={() => setOppNum(oppNum + 1)}>反对</Button>
<Button onClick={() => setX(x + 1)}>干点别的事</Button>
</div>
</div>
);
}
在上述代码中,我们把计算投票支持率的逻辑放在了 useMemo
内部,通过依赖项数组来指定只有在支持人数supNum
或反对人数oppNum
发生变化时才重新计算。这样,就可以避免在其他状态(比如 x
)发生变化时不必要地重新计算支持率。
思考缓存在哪里??
useMemo
钩子缓存的计算结果是存在内存中的,而不是浏览器中。具体来说,缓存计算结果是存在 React 内部的某个地方,这个地方是不可访问和控制的,仅限于 React 内部使用。
当组件重新渲染时,useMemo
钩子会判断依赖项数组中的值是否发生了变化。如果依赖项数组中的值与前一次渲染时的值不同,useMemo
钩子会调用计算函数,计算新的结果,并将结果缓存起来。如果依赖项数组中的值没有发生变化,useMemo
钩子就会直接返回上一次缓存的结果,避免重复计算。
需要注意的是,缓存的计算结果是存在内存中的,如果缓存的结果占用较大的内存空间,可能会导致组件的内存占用过高,从而影响应用的性能和稳定性。因此,在使用 useMemo
钩子时,要注意控制缓存大小,避免大量占用内存。
这个缓存是全局变量吗??
不是。相比全局变量,useMemo
钩子的缓存是更加局部的,它仅对当前组件实例内部可见和生效,不会影响到其他组件或全局变量。
举个例子,如果在一个 React 应用中有多个组件都使用了 useMemo
钩子来缓存计算结果,那么每个组件的计算结果都是独立存在的,不会互相干扰或影响其他组件。
而全局变量具有全局范围的作用域,多个组件或模块都可以访问和修改它,容易导致命名冲突和意外修改,造成不可预料的错误。
因此,使用 useMemo
钩子来缓存计算结果,既可以提高性能,又不会对其他组件造成影响,是一种更加优雅、可控、安全的方式。
useCallback
const xxX = useCallback( callback, [dependencies] )
组件第一次渲染,useCallback执行,创建一个函数"callback",赋值给×××
组件后续每一次更新,判断依赖的状态值是否改变,如果改变,则重新创建新的函数堆,赋值给xxX,但是如果,依赖的状态没有更新「或者没有设置依赖“[]"」则xxx获取的一直是第一次创建的函数堆,不会创建新的函数出来!!
useCallback不要乱用!并不是所有组件内部的函数,都拿其处理会更好!!+虽然减少了堆内存的开辟但是useCallback本身也有自己的处理逻辑和缓存的机制,这个也消耗时间啊
啥时候用它呢?
父组件嵌套子组件,父组件要把一个内部的函数,基于属性传递给子组件,此时传递的这个方法,我们基于useCallback处理一下会更好!!
父组件更新导致我们的子组件函数的地址发生改变,子组件就跟着跟新了!!!!如何解决??