为何使用useState却不声明状态更新函数?能否用useMemo替代?
为何使用useState却不声明状态更新函数?能否用useMemo替代?
这个问题问得很到位!我刚接触React的时候也纠结过这种只取useState第一个值的写法,咱们一步步拆解清楚:
为什么用useState却不写setter?
核心需求其实是在组件的整个生命周期里,保留一个不会随渲染重复创建的固定值。
React的useState有个关键特性:如果初始值是一个函数(比如代码里的useState(() => Symbol('instance-id'))),这个初始化函数只会在组件第一次渲染时执行一次,之后每次重新渲染都会直接复用之前生成的状态值,完全不会再调用这个初始化函数。就算你不声明状态更新函数,这个值也会稳稳地存在组件的状态容器里,直到组件卸载。
回到你看到的代码:
instanceId用Symbol生成唯一标识,目的就是让每个组件实例拥有独一份的ID,绝对不能每次渲染都生成新的Symbol,useState刚好完美满足“只创建一次”的需求。registry是getItemRegistry创建的实例,同样需要每个组件实例持有自己的独立注册器,不能每次渲染都新建一个,useState能保证这个实例从组件挂载到卸载都保持不变。
能不能用useMemo替代?
答案是不推荐,甚至可能引发奇怪的bug。
首先要明确:useMemo的设计初衷是性能优化工具——它用来缓存复杂计算的结果,避免每次渲染都重复执行昂贵的计算。但React官方明确说明:useMemo的缓存是“不可靠”的,React有权在某些场景下(比如后台组件、内存紧张时)主动丢弃缓存的结果,导致它重新执行计算函数。
如果用useMemo来替代这里的useState,万一React丢弃了缓存,就会重新生成一个新的instanceId或者registry,这就直接破坏了“每个组件实例对应唯一标识/注册器”的要求,很可能导致拖拽功能出现逻辑错误(比如拖拽系统识别错了组件实例)。
而useState的状态是React会严格保存在组件生命周期内的,不会随便丢弃,这才是符合这个场景需求的正确选择。
备注:内容来源于stack exchange,提问作者Alwaysblue
相关产品推荐
相关产品推荐

