react-use 版本演进全解析:从 1.0.0 到 17.6.1 的变更日志深度解读
【免费下载链接】react-useReact Hooks — 👍项目地址: https://gitcode.com/gh_mirrors/re/react-use
react-use 是一套开箱即用的 React Hooks 集合(仓库 package.json 中描述为 "Collection of React Hooks"),自 2018 年 10 月发布 1.0.0 以来持续迭代至今。本文以仓库根目录的 CHANGELOG.md 为骨架,逐版本梳理 react-use 的功能新增、Bug 修复与破坏性变更(Breaking Changes),并结合 src 目录下的源码实现,帮助你理解每个 Hook 的演进脉络、API 变迁原因,以及升级版本时需要关注的兼容性要点。读完本文,你将能快速定位某个 Hook 引入的版本、判断升级风险,并理解 react-use 内部架构重组的关键节点。
一、版本发布节奏与工程化基础
CHANGELOG.md 记录了从 1.0.0(2018-10-28)到 17.6.1(2026-06-10)的完整历史,共跨越约 8 年、数十个版本。从提交信息格式(如feat、fix、BREAKING CHANGES标记)可以看出,项目采用 Conventional Commits 规范,配合 package.json 中配置的semantic-release自动生成版本号与变更日志:
release脚本为semantic-release;- 发布分支包括
master与预发布分支next(prerelease 为rc); - 使用
@semantic-release/changelog、@semantic-release/npm、@semantic-release/git三个插件分别维护 CHANGELOG、发布 npm 包、提交版本信息。
这正是 CHANGELOG.md 中每个版本都带有compare/vX...vY比较链接和提交哈希的原因——日志是语义化发布流程的自动化产物。仓库当前的入口导出集中维护在 src/index.ts,其中可以看到大多数 Hook 的默认导出,而useKeyboardJs与useSpring因依赖较大的第三方库被注释掉,需要单独引入(对应 CHANGELOG 10.0.0 中"从 peerDependencies 中移除大体积库"的破坏性变更)。
二、v17 时代:稳定性维护与 React 18 适配
v17 系列是当前最新的主版本线,从 17.0.0(2021-01-31)到 17.6.1(2026-06-10),核心工作集中在适配 React 生态变化与少量 API 调整。
17.0.0:useNetwork 正式更名为 useNetworkState
17.0.0 是一次破坏性变更:useNetwork钩子被重命名为useNetworkState,源码见 src/useNetworkState.ts。该 Hook 返回一个包含联网状态的对象:
online:浏览器是否联网(boolean | undefined);previous:上一次的online值,用于判断刚连接还是刚断开;since:状态变化发生的Date对象;downlink/downlinkMax:估算带宽(Mbps);effectiveType:连接类型('slow-2g' | '2g' | '3g' | '4g');rtt:估算往返时延(毫秒);saveData:用户是否开启省流量模式;type:底层连接类型(bluetooth、cellular、ethernet、none、wifi、wimax、other、unknown)。
实现上,它监听window的online/offline事件,并兼容navigator.connection、navigator.mozConnection、navigator.webkitConnection的change事件(源码 src/useNetworkState.ts)。
17.3.x:useAudio 增加 playing 状态,性能优化
17.3.0 为useAudio增加了playing状态(此前媒体类 Hook 仅返回paused,见 12.0.0 的破坏性变更说明)。17.3.1 则优化了useTitle,仅在标题真正变化时才更新 DOM。这两个 Hook 分别由createHTMLMediaHook工厂(src/factory/createHTMLMediaHook.ts)和 src/useTitle.ts 实现。
17.4.x 与 17.5.x:新能力与依赖修正
- 17.4.0 新增
usePinchZoom传感器 Hook,用于监听双指缩放手势(实现见 src/usePinchZoom.ts); - 17.4.1、17.5.1 两次升级
nano-css依赖(服务于useCss等样式相关 Hook); - 17.5.0 为
useStateList增加isFirst与isLast返回值。
useStateList的完整返回结构在 src/useStateList.ts 中定义:state、currentIndex、setStateAt、setState、next、prev、isFirst、isLast。值得注意的实现细节是setStateAt支持越界回绕——索引为负数时从右侧倒数,超过列表长度时取模回到前面(src/useStateList.ts)。
17.6.x:useWindowSize 的 onChange 回调与依赖升级
17.6.0 为useWindowSize新增onChange回调;17.6.1 将js-cookie升级到 v3(服务于useCookie)。当前版本 src/useWindowSize.ts 的完整签名如下:
interface Options { initialWidth?: number; // 默认 Infinity initialHeight?: number; // 默认 Infinity onChange?: (width: number, height: number) => void; // 窗口尺寸变化时回调 } const useWindowSize = ({ initialWidth = Infinity, initialHeight = Infinity, onChange }: Options = {});其内部使用useRafState管理状态,通过requestAnimationFrame节流 resize 事件,并仅在isBrowser为真时挂载/解绑事件监听(src/useWindowSize.ts),这是它 SSR 友好的关键。
17.3.3:React 18 类型适配
17.3.3 解决了@types/react@18的破坏性变更(React.FC类型调整),并移除了对 React 版本的过旧 peer 依赖限制。升级到 v17 后,配合 React 18 使用已无障碍。
三、v16:目录架构重组
16.0.0 是一次典型的"结构性破坏性变更",不改变功能但改变导入路径:
- 所有
create*工厂函数被移入factory子目录,直接导入时应写为react-use/esm/factory/createBreakpoint形式; - 目录
comps更名为component。
对应到当前仓库结构,工厂类 Hook 统一位于 src/factory 下:createBreakpoint、createGlobalState、createHTMLMediaHook、createMemo、createReducer、createReducerContext、createRenderProp、createRouter、createStateContext。如果你在旧代码中使用了react-use/esm/createReducer之类的路径,升级后需要按新路径调整。
四、v15:useMeasure 与 useLocalStorage 的重写
15.0.0 是 v17 之前影响面最大的一次破坏性版本,主要围绕两个高频 Hook:
useMeasure 全面重构
- 不再使用
resize-observer-polyfill包,改为直接依赖原生ResizeObserver; - 默认值从全零改为
-1(若浏览器不支持或未测量到值); - 在服务端(SSR)以及没有
ResizeObserver的环境中会回退为 noop 实现。
当前源码 src/useMeasure.ts 印证了这一设计:模块导出时即判断isBrowser && typeof window.ResizeObserver !== 'undefined',否则导出返回[noop, defaultState]的占位函数。defaultState中x/y/width/height/top/left/bottom/right均为0——注意这与 CHANGELOG 描述的 "-1" 默认值存在差异,说明后续版本又对默认值做了调整(15.0.3 的 typings 修正与 17.2.1 的 SVG 类型支持也与此相关)。
useLocalStorage 能力增强
- 支持自定义
serializer/deserializer(13.18.0 引入); - 空值使用
undefined而非null; - 新增
remove功能(可从返回值中解构出第三个元素); - 改进序列化处理与 SSR 兼容。
当前实现 src/useLocalStorage.ts 返回[state, set, remove]三元组,支持raw: true模式(不经过 JSON 序列化)和自定义序列化函数,并且在 key 变化时通过useLayoutEffect重新初始化(对应 17.2.4 的 "reinitialize on key change" 修复)。
15.x 其他亮点
- 15.1.0 新增
useLatest,用于始终持有最新值的 ref(实现见 src/useLatest.ts); - 15.2.0 新增
useMouseWheel滚轮传感器 Hook; - 15.3.0 重做
usePrevious,更省内存(15.3.1 又因 issue #1315 回退了重写版本); - 15.3.8 改进
useStateValidator与useMultiStateValidator的类型定义。
五、v13–v14:功能爆发期
这一阶段(2019 年底到 2020 年中)是 react-use 新增 Hook 最密集的时期,绝大多数当前常用的 Hook 都在此间落地:
| 版本 | 新增功能 |
|---|---|
| 13.7.0 | useSet |
| 13.9.0 | useFirstMountState、useRendersCount |
| 13.10.0 | useStateHistory(即后来的useStateWithHistory) |
| 13.11.0 | useUnmountPromise |
| 13.12.0 | useScrollbarWidth |
| 13.13.0 | useShallowCompareEffect、useCustomCompareEffect |
| 13.15.0 | useCookie |
| 13.19.0 | useError |
| 13.22.0 | useLongPress |
| 13.23.0 | createGlobalState(全局状态工厂) |
| 13.24.0 | createReducerContext、createStateContext |
| 13.25.0 | useBeforeUnload支持传入 dirty 函数 |
| 13.26.0 | useMethods |
| 14.1.0 | useHash |
| 14.3.0 | useScratch |
| 15.0.0 | useScratch传感器 Hook 正式版 |
13.x 的破坏性变更
- 13.0.0:移除
useWait(它只是另一个包的简单再导出)、移除废弃的useRefMounted(请改用useMountedState); - 14.0.0:重做
useRafLoop,返回数组变为[stop, start, isActive],且循环启停不再导致父组件重新渲染。
值得关注的性能修复
- 13.10.2:修复
useUpdate计数器到达Number.MAX_SAFE_INTEGER后无法触发重渲染的问题; - 13.24.1:改用
fast-deep-equal进行深比较(服务于useDeepCompareEffect); - 13.12.1:
useMap的方法在渲染间保持稳定引用。
六、v12 及更早:基础 Hook 的积累
v12 之前是 react-use 的奠基期,很多"基础设施型"Hook 在此时出现:
- 4.9.0:
useSessionStorage、useWait; - 5.2.0:
useKeyPress(支持按键组合); - 5.9.0:
useAsyncRetry; - 5.12.0–5.14.0:
useWindowScroll、useScroll、useLockBodyScroll; - 6.0.0:
useClickAway(替代useOutsideClick); - 7.0.0:
useKey、useDrop、useDropArea、useEvent、usePageLeave、useThrottleFn等大批 Hook 集中发布; - 9.12.0:
useInterval; - 11.3.0:
usePreviousDistinct; - 12.4.0:
useIntersection; - 12.9.0:
createBreakpoint; - 12.13.0:引入
resolveHookState状态解析工具(见 src/misc/hookState.ts),useCounter、useGetSet借此重构,更贴近 React 的 setState 语义。
早期破坏性变更清单
升级旧版本项目时,以下 API 变迁需要特别注意:
| 版本 | 破坏性变更 |
|---|---|
| 2.0.0 / 3.0.0 / 9.0.0 | useToggle接口三次调整,最终接受任意值并转为布尔 |
| 4.0.0 | useCounter接口变更,新增useNumber别名 |
| 5.0.0 | 移除实验性 Hook:useRenderProp、useAsync |
| 6.0.0 | useOutsideClick更名为useClickAway;useCallbag移除;KeyboardJS、Rebound 改为单独安装 |
| 7.0.0 | useKeyPressEvent改为依赖注入并返回事件对象;useThrottle完全重写 |
| 8.0.0 | useCopyToClipboard接口变更 |
| 10.0.0 | useSpring、useKeyboardJs不再列入 peerDependencies,需直接导入 |
| 11.0.0 | useTimeout改为返回元组 |
| 12.0.0 | 媒体类 Hook(useAudio/useVideo)状态由isPlaying改为paused |
| 13.0.0 | 移除useWait、useRefMounted |
| 14.0.0 | useRafLoop返回值顺序改为[stop, start, isActive] |
| 15.0.0 | useMeasure、useLocalStorage实现重构,useAsyncFn保留旧结果 |
| 16.0.0 | create*工厂移入factory子目录,comps更名为component |
| 17.0.0 | useNetwork更名为useNetworkState |
七、源码验证:异步与生命周期 Hook 的稳定性修复
CHANGELOG 中反复出现useAsync系列、useUpdateEffect等 Hook 的修复记录,结合源码可以理解其设计意图:
- src/useAsyncFn.ts 使用
lastCallIdref 记录最近一次调用的 ID,仅在"组件仍挂载且本次调用仍是最新"时才写入状态,从而避免竞态(对应 13.8.1 "does not discard old promises and might produce races" 的修复,以及 15.0.0 "keep previous state in useAsyncFn" 的变更——调用期间保留上一次的value/error); - 15.1.1 将
useIsomorphicLayoutEffect应用到所有 Hook(src/useIsomorphicLayoutEffect.ts),统一了 SSR 下的 effect 行为; - 17.1.1 修复
useMountedState在componentDidUpdate阶段误改状态的问题,useMountedState现由 src/useMountedState.ts 实现,并被useAsyncFn、useStateList等复用。
这些细节说明:react-use 的版本历史不仅是"加功能",更是在持续打磨事件绑定(src/misc/util.ts 中的on/off/isBrowser工具)、SSR 兼容性与竞态处理。
八、如何查阅版本历史与制定升级策略
- 查看完整日志:仓库根目录的 CHANGELOG.md 记录了从 1.0.0 至今的全部条目,按"版本号 + 发布日期 + 变更类型(Features / Bug Fixes / Performance Improvements / BREAKING CHANGES)"组织,是最权威的升级参考;
- 核对导出面:升级前对照 src/index.ts 确认目标版本是否仍导出你使用的 Hook 及导入路径(尤其注意 16.0.0 的
factory目录调整和 10.0.0 起useSpring/useKeyboardJs需单独安装); - 关注 Breaking Changes 标记:本文第七节的表格汇总了历次破坏性变更,升级跨越多个大版本时建议逐个版本对照检查;
- 查阅对应文档与故事:每个 Hook 在 docs 目录有独立 Markdown 文档,在 stories 目录有 Storybook 演示用例(如 stories/useWindowSize.story.tsx),可用于验证新 API 的实际用法;
- 运行测试:仓库提供了完善的 Jest 测试集(tests 目录),升级后可通过
yarn test快速回归。
结语
透过 CHANGELOG.md 这份 2000 余行的版本日志,可以清晰看到 react-use 从一套基础 Hook 集合成长为覆盖传感器、状态管理、生命周期、UI 交互等多维度工具库的全过程。对使用者而言,掌握"哪个 Hook 在哪个版本出现、哪些版本引入了破坏性变更",是安全升级与排查兼容问题的关键。当前仓库处于 17.6.1,如果你的项目仍停留在 v15 或更早版本,建议参照本文的破坏性变更清单,重点核对useMeasure、useLocalStorage、useNetworkState、useRafLoop等 Hook 的 API 差异后再进行升级。
【免费下载链接】react-useReact Hooks — 👍项目地址: https://gitcode.com/gh_mirrors/re/react-use
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考