useMemo
useMemo 计算量大时的性能优化
作用:它在每次重新渲染的时候能够缓存计算的结果
是的,这个现象确实是由 React 的渲染机制直接导致的。具体原因和机制可以分解如下:
一、React 函数组件的渲染本质
React 函数组件的核心特征是每次状态更新都会触发整个函数体的重新执行(包括所有变量初始化、函数调用等逻辑)这是 React 响应式编程模型的核心设计
看一个场景
下面我们的本来的用意是想基于count的变化计算斐波那契数列之和,但是当我们修改num状态的时候,斐波那契求和函数也会被执行,显然是一种浪费
// useMemo
// 作用:在组件渲染时缓存计算的结果
import { useState } from 'react'
function factorialOf(n) {
console.log('斐波那契函数执行了')
return n <= 0 ? 1 : n * factorialOf(n - 1)
}
function App() {
const [count, setCount] = useState(0)
// 计算斐波那契之和
const sumByCount = factorialOf(count)
const [num, setNum] = useState(0)
return (
<>
{sum}
<button onClick={() => setCount(count + 1)}>+count:{count}</button>
<button onClick={() => setNum(num + 1)}>+num:{num}</button>
</>
)
}
export default App
useMemo缓存计算结果
思路: 只有count发生变化时才重新进行计算
import { useMemo, useState } from 'react'
function fib (n) {
console.log('计算函数执行了')
if (n < 3) return 1
return fib(n - 2) + fib(n - 1)
}
function App() {
const [count, setCount] = useState(0)
// 计算斐波那契之和
// const sum = fib(count)
// 通过useMemo缓存计算结果,只有count发生变化时才重新计算
const sum = useMemo(() => {
return fib(count)
}, [count])
const [num, setNum] = useState(0)
return (
<>
{sum}
<button onClick={() => setCount(count + 1)}>+count:{count}</button>
<button onClick={() => setNum(num + 1)}>+num:{num}</button>
</>
)
}
export default App
useMemo 和 useEffect区别
useMemo优化渲染性能,useEffect管理副作用。
useMemo 和 useEffect 是 React 中两个核心 Hook,虽然都能响应依赖变化,但设计目的和使用场景截然不同。以下是它们的核心区别及使用建议:
一、核心机制对比
特性 | useMemo | useEffect |
---|---|---|
执行时机 | 在 渲染期间同步执行,计算结果直接参与当前渲染流程 | 在 渲染完成后异步执行(浏览器完成布局和绘制后) |
主要用途 | 缓存 计算成本高 的值或对象引用,优化渲染性能 | 处理 副作用(如 API 调用、DOM 操作、订阅/取消订阅事件) |
返回值 | 返回计算结果,可直接用于渲染或其他逻辑 | 无返回值(但可返回 清理函数,用于组件卸载时执行清理操作) |
依赖变化影响 | 立即重新计算,确保当前渲染使用最新值 | 延迟执行,在下次渲染后根据依赖变化执行副作用操作 |
性能影响 | 避免重复计算,但过度使用会增加内存开销 | 异步执行不阻塞渲染,但频繁触发可能导致循环渲染或性能问题 |