文章目录
- [🚀 React 惰性初始化函数(Lazy Initializer)详解](#🚀 React 惰性初始化函数(Lazy Initializer)详解)
-
- [一、`useState` 的两种初始化方式](#一、
useState的两种初始化方式) - 二、为什么会这样?
-
- [🧩 1. 直接传入初始值](#🧩 1. 直接传入初始值)
- [⚙️ 2. 传入一个函数(惰性初始化)](#⚙️ 2. 传入一个函数(惰性初始化))
- 三、为什么要使用惰性初始化?
- 四、一个真实例子
- [五、常见误区 ⚠️](#五、常见误区 ⚠️)
- 六、总结
- [🧠 小结](#🧠 小结)
- [一、`useState` 的两种初始化方式](#一、
🚀 React 惰性初始化函数(Lazy Initializer)详解
在使用
useState时,你是否注意到有两种初始化写法?一种是直接传入初始值,另一种是传入一个函数。
它们的区别是什么?为什么有时候我们需要传一个函数?
这就是本文要讲的主角 ------ 惰性初始化函数(lazy initializer)。
一、useState 的两种初始化方式
我们先从最常见的写法开始:
js
// 写法 1:直接传入初始值(注意:此种方法也等价于传入立即执行函数)
const [value, setValue] = useState(heavyCompute());
js
// 写法 2:传入一个函数
const [value, setValue] = useState(() => heavyCompute());
这两种写法的区别在于:
第一种每次渲染都会执行
heavyCompute(),第二种只会在首次渲染时执行一次。
二、为什么会这样?
要理解这一点,我们得看看 React 是怎么处理这两种情况的。
🧩 1. 直接传入初始值
当你写成:
js
useState(heavyCompute());
React 在调用你的组件函数时,会立即执行 heavyCompute(),
因为这就是一个普通的函数调用。然后把返回值传给 useState 作为初始值。
也就是说,即使 React 只是为了重新渲染(而不是重新挂载),
heavyCompute() 仍然会在组件函数执行阶段被调用。
结果就是:
每次组件渲染都会重新计算初始值 ------ 即使 React 根本不会再用它。
⚙️ 2. 传入一个函数(惰性初始化)
而当你写成:
js
useState(() => heavyCompute());
React 会识别到你传入的是一个函数 ,
这时它不会立刻执行,而是把这个函数存起来。
在组件第一次渲染时 ,React 内部才会调用这个函数来获得初始值。
之后,无论组件重新渲染多少次,这个函数都不会再被执行。
因此,它被称为 惰性初始化函数(Lazy Initializer)。
三、为什么要使用惰性初始化?
主要原因是 ------ 性能优化。
如果你的初始 state 计算逻辑非常复杂,比如:
- 要从
localStorage或数据库中读取; - 要进行大量数据计算;
- 或者要从一个大对象中筛选出初始状态;
那这些操作每次渲染时执行一次都会造成性能浪费。
使用惰性初始化函数后,计算只会在首次渲染时执行一次,大幅减少不必要的计算成本。
四、一个真实例子
假设我们要从本地存储中加载用户设置:
js
function App() {
const [settings, setSettings] = useState(() => {
console.log('只执行一次');
const stored = localStorage.getItem('settings');
return stored ? JSON.parse(stored) : getDefaultSettings();
});
return <SettingsPanel settings={settings} />;
}
✅ 优点:
- 组件每次更新时,不会重复执行
localStorage.getItem(); - 初始化逻辑清晰且性能友好;
- React 官方推荐这种写法处理"昂贵初始化逻辑"。
五、常见误区 ⚠️
| 写法 | 是否惰性执行 | 执行次数 | 说明 |
|---|---|---|---|
useState(heavyCompute()) |
❌ 否 | 每次渲染都会执行 | 函数被立即调用 |
useState(() => heavyCompute()) |
✅ 是 | 只在首次渲染执行 | 惰性初始化函数 |
useState((() => heavyCompute())()) |
❌ 否 | 每次渲染都会执行 | 立即执行函数,与第一种等价 |
六、总结
| 特性 | 惰性初始化函数 |
|---|---|
| 写法 | useState(() => initValue) |
| 执行时机 | 仅在首次渲染时执行 |
| 适用场景 | 初始化逻辑复杂或性能开销大的场景 |
| 好处 | 避免重复计算、提升性能 |
| 常见错误 | 误用 useState(fn()) 导致重复执行 |
🧠 小结
当你的初始值计算过程昂贵 或依赖外部资源时,
请使用 React 的 惰性初始化函数:
jsconst [value, setValue] = useState(() => heavyCompute());这样 React 只会在首次渲染时调用它一次,让组件更高效、更优雅。