React惰性初始化函数(Lazy Initializer)(首次渲染时执行一次,只执行一次,应对昂贵初始化逻辑)(传入一个函数、传入函数)

文章目录

  • [🚀 React 惰性初始化函数(Lazy Initializer)详解](#🚀 React 惰性初始化函数(Lazy Initializer)详解)

🚀 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 的 惰性初始化函数

js 复制代码
const [value, setValue] = useState(() => heavyCompute());

这样 React 只会在首次渲染时调用它一次,让组件更高效、更优雅。


相关推荐
程序员黑豆5 小时前
Java 注释详解:单行、多行与文档注释的完整指南
java·前端·ai编程
剪刀石头布啊5 小时前
antd中可编辑表格中巧用useWatch实现联动高性能效果,以及定制延伸学习
前端
油丶酸萝卜别吃6 小时前
前端转全栈学习路线
前端·学习
浮生望6 小时前
前端路由进阶:History API原理与手写HistoryRouter
前端
陆枫Larry6 小时前
JavaScript 中的竞态是什么,为啥会有竟态?
前端
上海安当技术8 小时前
半天接入:USBKey RESTful API + C 动态库,Web 和 C/S 两套集成路径实战
前端·后端·restful·集成·usbkey
DevUI团队9 小时前
从“即兴创作”到“规格先行”,华为云码道(CodeArts)代码智能体持续深耕企业级规范驱动开发能力
前端·人工智能·后端
weixin_4316004410 小时前
NestJS 入门(3):Guard 如何挡住未登录请求?
前端·后端·学习·nest.js
avi911110 小时前
[AI教做人]AI平台做2项目;一个3D模型展示,另一个框架多人
javascript·人工智能·ai·3d模型·3d引擎·顶点和法线
kyriewen10 小时前
我用Claude Code两天干完了团队两周的排期——周报发出去那一刻我就后悔了
前端·javascript·ai编程