【React】useMemo 和 useEffect 的用法

两者的核心区别在于“何时执行、做什么、返回什么

作用

useMemo:在渲染期间计算并缓存一个“值”。目的是避免重复的昂贵计算或保持引用稳定(对象/数组/派生结果)。
useEffect:在渲染提交到 DOM 之后执行“副作用”。目的是与外部世界交互或处理需要在渲染后进行的事情(订阅、请求、操作 DOM、日志等)。

执行时机

useMemo:在组件渲染过程中同步运行计算(不触发浏览器绘制前就算完),返回值直接用于本次渲染。
useEffect:在浏览器完成绘制后异步运行(非阻塞渲染)。不会影响本次渲染的输出,只在提交后执行。

返回值

useMemo:返回计算结果(任何值:对象、数组、数字、函数等)。
useEffect:不返回值给渲染;可以返回一个清理函数用于卸载或依赖变化时清理副作用。

依赖变化时的行为

useMemo:依赖不变则复用上次结果;依赖变则在下一次渲染时重新计算值。
useEffect:依赖不变则不重新执行;依赖变则在提交后执行清理函数(若有)然后再运行副作用。

适用场景

useMemo:
重计算优化(过滤、排序、派生数据)。
保持引用稳定,避免把“每次都新建的对象/数组”传给子组件导致不必要渲染。
useEffect:
发起网络请求、订阅/取消订阅、事件监听、操作 DOM、计时器、日志、与外部存储交互等“副作用”。

常见误用对比

不要用 useEffect 去“计算一个值再 setState”来参与同一轮渲染,这会导致额外渲染;应使用 useMemo 在渲染期间直接算出值。
不要用 useMemo 做副作用(如请求、打印日志、修改外部变量);useMemo 仅用于纯计算,不能产生副作用。

与性能相关

useMemo 自身有开销,只有当计算成本高或引用稳定性能明显减少渲染时再用。
useEffect 异步执行,不阻塞渲染,但如果依赖频繁变化且在 Effect 中做重活,也会造成抖动或资源浪费。

简易判断

我只是需要一个由 props/state 派生出来的值,并且它应该在渲染时就可用且无副作用 → useMemo
我需要在组件渲染提交后与外部系统交互或安排清理 → useEffect

小例子:

useMemo:const sorted = useMemo(() => sort(items), [items])
useEffect: useEffect(() => { const id = setInterval(tick, 1000) return () => clearInterval(id) }, [])

实例直观理解

下面用两个并排对比的小例子,直观理解什么时候用 useMemo,什么时候用 useEffect + setState,以及为什么前者更合适做“纯派生计算”。

例子背景

有一份列表 allUsers,你可以通过 selectedRoles 来筛选用户。
我们在界面上展示筛选后的用户。

一、用 useEffect + setState(不太合适的做法)
说明:用 Effect 做纯计算,会导致多一次渲染;同时需要维护额外状态,容易产生同步问题。

代码片段

function Users({
    
     allUsers, selectedRoles }) {
   
   
const [filteredUsers, setFilteredUsers] = useState(allUsers);

useEffect(() => {
   
   
// 纯计算:根据依赖派生值
const next = selectedRoles.length
? allUsers.filter<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值