You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useState(0)与useState(()=>0)的差异及使用注意事项

1. 需要给useState传入箭头函数做初始化参数的场景

核心只有两类场景适合用这种写法:

  • 初始值计算开销很高的时候。比如要从localStorage读取大容量数据做解析、遍历上千条数据做格式化、执行复杂的数学计算等。useState直接传值的话,不管组件第几次渲染,这个计算逻辑都会完整执行一遍(哪怕React只会用第一次的计算结果当初始值);传入箭头函数属于惰性初始化,React只会在组件首次挂载时执行一次这个函数拿到初始值,后续重渲染完全跳过计算,能省掉大量不必要的性能开销。示例:
// 不好:每次渲染都会执行JSON.parse解析大字符串
const [bigData, setBigData] = useState(JSON.parse(localStorage.getItem('10mb_data') || '{}'))
// 好:仅首次挂载时解析一次
const [bigData, setBigData] = useState(() => JSON.parse(localStorage.getItem('10mb_data') || '{}'))
  • 初始化逻辑较长、需要多步条件判断的时候。把多步逻辑包在初始化函数里,比直接把三目运算、多段逻辑判断堆在useState的参数位置可读性好很多。
2. 能不能无差别在所有React Hook初始化环节统一用箭头函数传参

绝对不行。

  • 首先React内置Hook里,只有useState、useReducer(第三个参数为初始化函数)原生支持函数形式的惰性初始化逻辑,其他Hook根本不会自动执行你传入的函数来生成初始值。比如给useRef传入箭头函数:
// 不符合预期:ref.current存的是箭头函数本身,不是HeavyClass的实例
const heavyRef = useRef(() => new HeavyClass())
// 要拿到实例你得自己调用:heavyRef.current(),完全违背useRef存实例的初衷

像useContext、useImperativeHandle、useLayoutEffect、useDebugValue这些Hook,传入函数要么是作为固定的回调逻辑(比如effect的执行函数),要么根本不识别函数参数,乱传只会拿到不符合预期的结果甚至直接报错。

  • 就算是支持惰性初始化的useState,如果初始值是固定的基本类型值(比如0、false、固定字符串),每次都包一层箭头函数反而会多一层无意义的函数调用开销,属于纯纯的画蛇添足,没有任何收益。
3. 这种写法的常见坑点
  • 误以为初始化函数会在每次渲染执行,写出状态不同步的bug。useState的初始化函数仅在组件首次挂载时执行一次,后续就算依赖的props、上下文变了,初始值也不会自动更新。比如写const [count, setCount] = useState(() => props.initCount),后续父组件修改传入的initCount,本地的count状态完全不会跟着变,新手很容易在这里踩坑。
  • 在初始化函数里写副作用。useState的初始化函数要求必须是纯函数,如果你在里面写了接口请求、事件绑定、全局变量修改这类逻辑,在React严格模式下React会故意执行两次初始化函数来检测不规范写法,直接导致副作用重复执行,出很难排查的问题。
  • 存函数类型状态时写法错误。如果你的状态本身就是一个函数(比如存一个事件回调、工具方法),直接写useState(() => targetFn)的话,React会执行这个箭头函数,把targetFn的返回值当成初始状态,而不是targetFn本身。要存函数的话必须包两层:useState(() => () => targetFn),外层是给React识别的初始化函数,返回的内层函数才是真正的状态值。
  • 混淆初始化函数和更新阶段的函数传参。类组件setState传函数、useState返回的set方法传函数,是为了拿到前一次的状态值做增量更新,和初始化阶段传惰性函数的执行时机、作用完全不一样,不要把两者的逻辑混写。

内容的提问来源于stack exchange,提问作者Data T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:33:31