Skyroc Admin Docs
Shared

@skyroc/hooks

跨端 React hooks 集合,主入口 RN 安全,./web 子入口提供浏览器专用 hooks

概览

包名@skyroc/hooks
目录packages/hooks
版本1.0.0
运行时依赖ahooks
peerreact >= 18.0.0
子入口../web
测试✅ 9 个

@skyroc/hooks 把项目中跨端复用的 React hooks 收拢成一个包。设计上严格区分**「RN 安全」与「Web 专用」**两个层级,避免 Native 端误打包浏览器 API。

子入口边界

入口包含内容适用平台
.Store + 业务无关 hooksWeb / RN / MiniApp
./web主入口全部 + 浏览器 DOM hooks仅浏览器
import { useCaptcha } from '@skyroc/hooks';         // ✅ 跨端
import { useCopy } from '@skyroc/hooks/web';        // ✅ 仅 Web

Hook 清单

主入口(.

Hook用途
useArray数组状态(push / pop / filter / clear 等便捷方法)
useCaptcha验证码倒计时(含手机号校验、目标校验、自定义文案)
useCountDownTimer通用倒计时器
useLoadingloading 状态(含 setLoadingwithLoading(fn)
useNow实时时间(带可选刷新频率)
useStore订阅 Store<S> 实例(基于 useSyncExternalStore

./web 额外

Hook用途
useCopy调用剪贴板 API
useSystemTheme监听 (prefers-color-scheme: dark)

Store + useStore 模式

import { Store, useStore } from '@skyroc/hooks';

class CounterStore extends Store<{ count: number }> {
  constructor() {
    super({ count: 0 });
  }

  increment() {
    this.setState({ count: this.state.count + 1 });
  }
}

const counter = new CounterStore();

// 组件中
const { count } = useStore(counter);
counter.increment();

设计思路:class 管理逻辑与状态,useStore 桥接到 React。相比 jotai 更面向 OOP,相比 Zustand 更轻量、可继承。详细使用见 packages/hooks/src/store/README.md

useCaptcha 示例

const { count, label, start, isCounting, sendCaptcha } = useCaptcha({
  duration: 60,
  request: async phone => {
    await fetchSendCode(phone);
  },
  validateTarget: phone => REG_PHONE.test(phone),
  countingLabel: count => `${count}s 后重试`,
  idleLabel: '发送验证码'
});

<Button disabled={isCounting} onClick={() => sendCaptcha(phone)}>
  {label}
</Button>;

ahooks 是内部实现

包没有 re-export ahooks 的 hook,而是封装特定 hook 形成更直接的 API。如果业务想用 ahooks 的其它 hook,直接 import { useXxx } from 'ahooks' 即可。

跨端策略

主入口(src/index.ts)的所有 hooks 都遵循「不依赖浏览器或 RN API」的原则:

  • useArray / useLoading / useStore 纯 JS
  • useCaptcha / useCountDownTimersetTimeout
  • useNowsetInterval

需要 DOM 的 hooks 全部放 ./web

  • useCopynavigator.clipboard
  • useSystemThemewindow.matchMedia
// ❌ Native 端:会引入浏览器 API 报错
import { useCopy } from '@skyroc/hooks/web';

// ✅ Native 端:只用主入口
import { useArray, useLoading } from '@skyroc/hooks';

./webindex.ts 还会 export * from '../index' re-export 主入口,所以 Web 端只 import './web' 一处即可。

目录结构

src/
├── index.ts                    # 主入口(RN 安全)
├── use-array.ts
├── use-captcha.ts
├── use-count-down-timer.ts
├── use-loading.ts
├── use-now.ts
├── store/
│   ├── store.ts                # Store<S> 基类
│   ├── use-store.ts            # useStore hook
│   └── README.md               # store 详细文档
└── web/
    ├── index.ts                # Web 子入口(含主入口 re-export)
    ├── use-copy.ts
    └── use-system-theme.ts

在项目中的消费

  • @skyroc/web-admin-layouts:使用 useArrayuseStore
  • @skyroc/web-admin-theme:使用 useSystemTheme 跟随系统暗色
  • apps/admin / apps/admin-example:在登录页用 useCaptcha

测试覆盖

9 个测试文件覆盖 Store、各 hook 与 web 子入口。Hook 测试用 @testing-library/reactrenderHook

On this page