useRefState
package version >0.2.0
shadcn any version
author: cmtlyt
update time: 2026/04/07 11:16:55
一个结合了 ref 和 state 特性的 React Hook,提供灵活的状态管理能力。状态存储在 ref 中,避免了闭包陷阱问题,同时支持选择性地触发组件重新渲染。
特性
- 避免闭包陷阱:状态存储在
ref中,始终能获取最新值 - 灵活的渲染控制:可以选择是否触发组件重新渲染
- 完整的控制 API:提供多种状态操作方法
- 深拷贝支持:自动进行状态深拷贝,确保数据隔离
- 类型安全:完整的 TypeScript 类型支持
安装
npm
shadcn
用法
基础示例
简单状态管理
对象状态管理
高级示例
不触发渲染的状态更新
在事件处理器中使用
复杂状态管理
API
useRefState
参数
initialState: T- 初始状态值
返回值
返回一个元组:
[0]: T- 当前状态值[1]: UseRefStateCtrl<T>- 控制对象
UseRefStateCtrl
控制对象包含以下方法:
patchState
更新状态的局部字段。
参数:
updater: (draft: T) => void- 更新函数,直接修改 draft 对象update?: boolean- 是否触发组件重新渲染,默认为true
示例:
forceUpdate
强制组件重新渲染。
示例:
getState
获取当前状态的最新值。
返回值: 当前状态值
示例:
setState
设置新的状态值。
参数:
state: T- 新的状态值update?: boolean- 是否触发组件重新渲染,默认为true
示例:
reset
重置状态为初始值。
参数:
update?: boolean- 是否触发组件重新渲染,默认为true
示例:
使用场景
1. 避免闭包陷阱
在事件处理器、定时器、异步操作中,useRefState 可以避免闭包问题:
2. 批量更新优化
当需要执行多个状态更新但只想触发一次渲染时:
3. 复杂对象状态管理
对于复杂的嵌套对象,patchState 提供了便捷的更新方式:
4. 表单状态管理
注意事项
1. 状态深拷贝
状态会自动进行深拷贝处理,这意味着:
- 优点:确保数据隔离,避免引用问题
- 缺点:对于大型对象可能影响性能
- 建议:对于大型对象,考虑使用浅拷贝或不可变数据结构
2. 渲染控制
- 默认情况下,所有状态更新都会触发组件重新渲染
- 使用
update: false参数可以避免触发渲染,适用于批量操作 - 记得在批量操作完成后调用
forceUpdate()触发渲染
3. 与 useState 的区别
4. TypeScript 类型推断
确保为泛型参数提供正确的类型:
5. 性能考虑
- 对于频繁更新的状态,考虑使用
update: false批量处理 - 对于大型对象,评估深拷贝的性能影响
- 在需要时使用
forceUpdate()手动控制渲染时机
常见问题
Q: 什么时候应该使用 useRefState 而不是 useState?
A: 当你需要:
- 在闭包中访问最新状态值
- 批量更新状态并控制渲染时机
- 管理复杂的嵌套对象状态
- 在事件处理器或定时器中更新状态
Q: 如何在不触发渲染的情况下更新状态?
A: 使用 patchState 或 setState 的第二个参数:
Q: reset 方法会重置为什么值?
A: reset 会将状态重置为调用 useRefState 时传入的初始值。
Q: 可以在 useEffect 中使用吗?
A: 可以,而且特别适合在 useEffect 中使用,因为可以避免闭包陷阱: