npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@basestone/hooks

v1.5.0

Published

一套用于 React + Ant Design 应用的生产级 Hooks 库,提供表格管理、模态框管理、表单提交、数据请求等常用功能。

Downloads

1,142

Readme

@basestone/hooks

一套用于 React + Ant Design 应用的生产级 Hooks 库,提供表格管理、模态框管理、表单提交、数据请求等常用功能。

npm version license

✨ 特性

  • 🎯 开箱即用 - 提供常用业务场景的完整解决方案
  • 💪 TypeScript - 完整的类型定义和类型推导
  • 🎨 Ant Design - 深度集成 Ant Design 组件
  • ⚡️ 性能优化 - 内置性能优化和记忆化
  • 🔧 灵活配置 - 支持全局配置和局部定制

📦 安装

pnpm add @basestone/hooks
# or
npm install @basestone/hooks
# or
yarn add @basestone/hooks

📚 Hooks 列表

🔧 Claude Code Skill

本库提供了 Claude Code Skill,可以在使用 Claude Code 开发时快速获取帮助和代码示例。

查看 Skill 文档 了解如何在你的项目中使用。

📖 使用文档

useTableList - 表格管理

提供完整的表格管理功能,包括分页、排序、加载状态、行选择等。

import { useTableList } from '@basestone/hooks'
import { Table } from 'antd'

function UserList() {
  const { tableProps, search, refresh, reset, queryParams, selectedRowKeys } = useTableList({
    queryFn: async (params) => {
      // API 返回格式: { status: 'success', data: { list: [], totalCount: 0 } }
      return await getUserList(params)
    },
    params: {
      orderField: 'createDate',
      orderType: 'DESC',
      status: 'active'
    },
    // 可选:缓存查询条件。默认关闭;key 用于同一列表再次挂载时恢复条件
    queryCache: {
      enabled: true,
      key: 'user-list'
    },
    rowSelection: true // 启用行选择
  })

  return (
    <div>
      <button onClick={() => search({ keyword: 'test' })}>搜索</button>
      <button onClick={() => refresh()}>刷新</button>
      <Table
        rowKey="id"
        scroll={{ x: 'max-content' }}
        columns={columns}
        {...tableProps}
      />
    </div>
  )
}

API:

  • tableProps - Ant Design Table 所需的所有属性
  • search(params) - 搜索并重置到第一页
  • refresh(params) - 刷新当前页
  • reset(params) - 重置查询参数
  • queryParams - 当前查询参数
  • selectedRowKeys - 选中的行 keys

queryCache 默认不启用。启用后,queryParams 会按 key 缓存在 Zustand store 中, 相同 key 的列表再次挂载时会自动恢复上一次查询条件:

useTableList({
  queryFn: getUserList,
  queryCache: { enabled: true, key: 'user-list' }
})

需要时可以通过相同的 key 清除指定缓存;不传 key 时清除全部表格查询参数:

import { clearTableQueryCache, setTableQueryCache } from '@basestone/hooks'

// 与该 key 已有的查询参数合并
setTableQueryCache('user-list', { status: 'active' })
clearTableQueryCache('user-list')
clearTableQueryCache()

useCreateModal - 模态框管理

使用 zustand 管理多个模态框的状态,支持 Modal 和 Drawer。

import { useCreateModal } from '@basestone/hooks'
import { Modal, Drawer } from 'antd'

function UserManagement() {
  const { editModal, viewModal, open, close, toggle } = useCreateModal({
    edit: {
      width: 600,
      title: (data) => data?.id ? '编辑用户' : '创建用户',
      centered: true,
      maskClosable: false
    },
    view: {
      width: 800,
      title: '用户详情',
      placement: 'right' // Drawer 配置
    }
  })

  return (
    <div>
      <button onClick={() => open('edit', { id: 1, name: 'John' })}>
        编辑用户
      </button>

      {/* 作为 Modal 使用 */}
      <Modal {...editModal.modalProps}>
        <div>用户数据: {JSON.stringify(editModal.data)}</div>
      </Modal>

      {/* 作为 Drawer 使用 */}
      <Drawer {...viewModal.drawerProps}>
        <div>用户详情: {JSON.stringify(viewModal.data)}</div>
      </Drawer>
    </div>
  )
}

API:

  • {name}Modal.modalProps - Modal 组件属性
  • {name}Modal.drawerProps - Drawer 组件属性
  • {name}Modal.visible - 可见状态
  • {name}Modal.data - 传入的数据
  • open(type, data) - 打开指定模态框
  • close(type) - 关闭指定模态框
  • toggle(type, data) - 切换指定模态框

useSelectOptions - 下拉选项管理

自动获取和管理下拉选项,并创建 value-label 映射。

import { useSelectOptions } from '@basestone/hooks'
import { Select } from 'antd'

function UserFilter() {
  const { departmentOptions, departmentMap, loading, refresh } = useSelectOptions({
    queryFn: async (params) => {
      // API 返回格式: { status: 'success', data: [] }
      return await getDepartmentList(params)
    },
    params: { active: true },
    dataKey: 'department', // 会创建 departmentOptions 和 departmentMap
    fieldNames: {
      label: 'departmentName',
      value: 'departmentId'
    },
    transform: (data) => data.filter(item => item.visible) // 可选的数据转换
  })

  return (
    <Select
      options={departmentOptions}
      loading={loading}
      onChange={(value) => {
        console.log('选中值:', value)
        console.log('对应标签:', departmentMap.get(value))
      }}
    />
  )
}

API:

  • {dataKey}Options - 格式化后的选项数组 { label, value, data }
  • {dataKey}Map - value 到 label 的映射 Map
  • loading - 加载状态
  • refresh() - 刷新选项

useRequestQuery - 数据请求

通用的数据请求 Hook,支持 Object 和 Array 类型数据。

import { useRequestQuery } from '@basestone/hooks'

function UserProfile({ userId }) {
  // 请求单个对象
  const { userInfo, setUserInfo, loading, refresh } = useRequestQuery({
    queryFn: async (params) => {
      // API 返回格式: { status: 'success', data: {...} }
      return await getUserInfo(params)
    },
    params: { userId },
    dataKey: 'userInfo',
    dataType: 'Object',
    initialValue: { name: '', email: '' },
    transform: (data) => ({
      ...data,
      fullName: `${data.firstName} ${data.lastName}`
    }),
    success: (data) => {
      console.log('数据加载成功:', data)
    }
  })

  // 请求数组数据
  const { notificationList, setNotificationList } = useRequestQuery({
    queryFn: getNotificationList,
    params: { userId },
    dataKey: 'notificationList',
    dataType: 'Array',
    initialValue: []
  })

  // 手动更新数据
  const handleUpdateName = () => {
    setUserInfo(prev => ({ ...prev, name: '新名字' }))
  }

  const markAsRead = (id) => {
    setNotificationList(prev =>
      prev.map(item => item.id === id ? { ...item, read: true } : item)
    )
  }

  return (
    <div>
      {loading ? '加载中...' : (
        <div>
          <h1>{userInfo?.fullName}</h1>
          <p>{userInfo?.email}</p>
          <button onClick={handleUpdateName}>修改名字</button>
        </div>
      )}
    </div>
  )
}

API:

  • {dataKey} - 请求到的数据
  • set{DataKey} - 手动更新数据的函数,支持直接设置或函数式更新
  • loading - 加载状态
  • refresh(params) - 刷新数据

useFormSubmit - 表单提交

处理表单提交,自动管理加载状态和消息提示。

import { useFormSubmit } from '@basestone/hooks'
import { Form, Input, Button, App } from 'antd'

function UserForm({ onSuccess }) {
  const [form] = Form.useForm()

  const { loading, submit } = useFormSubmit(
    async (values) => {
      // API 返回格式: { status: 'success', info: '操作成功' }
      return await createUser(values)
    },
    (result) => {
      form.resetFields()
      onSuccess?.(result)
    }
  )

  return (
    <App> {/* 必需:message API 依赖 */}
      <Form form={form} onFinish={submit}>
        <Form.Item name="name" label="姓名" rules={[{ required: true }]}>
          <Input />
        </Form.Item>
        <Button type="primary" htmlType="submit" loading={loading}>
          提交
        </Button>
      </Form>
    </App>
  )
}

API:

  • loading - 提交中状态
  • submit(values) - 提交函数

useMemoizedFn - 函数记忆化

创建一个稳定引用的函数,但始终调用最新的实现。

import { useMemoizedFn } from '@basestone/hooks'
import { useEffect } from 'react'

function Component() {
  const [count, setCount] = useState(0)

  // 函数引用永不改变,但总是调用最新的实现
  const handleClick = useMemoizedFn(() => {
    console.log('当前 count:', count) // 总是打印最新的 count
    setCount(count + 1)
  })

  useEffect(() => {
    // handleClick 不会导致 effect 重新运行
  }, [handleClick])

  return <button onClick={handleClick}>点击 {count}</button>
}

🎯 完整示例

import {
  useTableList,
  useCreateModal,
  useSelectOptions,
  useFormSubmit
} from '@basestone/hooks'
import { Table, Modal, Form, Input, Select, Button, Space } from 'antd'

function UserManagement() {
  const [form] = Form.useForm()

  // 表格管理
  const { tableProps, refresh } = useTableList({
    queryFn: getUserList,
    params: { status: 'active' },
    rowSelection: true
  })

  // 模态框管理
  const { editModal, open, close } = useCreateModal({
    edit: {
      width: 600,
      title: (data) => data?.id ? '编辑' : '创建'
    }
  })

  // 下拉选项
  const { roleOptions } = useSelectOptions({
    queryFn: getRoleList,
    dataKey: 'role',
    fieldNames: { label: 'roleName', value: 'roleId' }
  })

  // 表单提交
  const { loading, submit } = useFormSubmit(
    async (values) => {
      const api = editModal.data?.id ? updateUser : createUser
      return api({ ...values, id: editModal.data?.id })
    },
    () => {
      close('edit')
      refresh()
    }
  )

  const columns = [
    { title: '姓名', dataIndex: 'name' },
    { title: '邮箱', dataIndex: 'email' },
    {
      title: '操作',
      render: (_, record) => (
        <Space>
          <Button onClick={() => open('edit', record)}>编辑</Button>
        </Space>
      )
    }
  ]

  return (
    <div>
      <Button onClick={() => open('edit')}>创建用户</Button>
      <Table rowKey="id" columns={columns} {...tableProps} />

      <Modal {...editModal.modalProps}>
        <Form form={form} onFinish={submit} initialValues={editModal.data}>
          <Form.Item name="name" label="姓名" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="roleId" label="角色">
            <Select options={roleOptions} />
          </Form.Item>
          <Button type="primary" htmlType="submit" loading={loading}>
            提交
          </Button>
        </Form>
      </Modal>
    </div>
  )
}

🔌 API 响应格式

所有请求函数应返回以下格式:

// 成功响应
{
  status: 'success',
  data: any, // 实际数据
  info?: string // 可选的消息
}

// useTableList 专用格式
{
  status: 'success',
  data: {
    list: any[], // 数据列表
    totalCount: number // 总数
  }
}

🎨 全局配置

表格全局配置

import { configureTableOption } from '@basestone/hooks'

configureTableOption({
  sortField: ['orderType', 'orderField'], // 排序字段名
  sortOrder: ['ASC', 'DESC'], // 排序顺序值
  pageSize: 20 // 默认每页条数
})

💡 最佳实践

  1. 错误处理: 所有 hooks 内部处理错误,但应确保 API 返回正确的响应格式
  2. 加载状态: 利用提供的 loading 状态提升用户体验
  3. 函数记忆化: 对于传递给子组件的回调,使用 useMemoizedFn
  4. 模态框状态: 模态框状态使用 zustand 全局管理,跨渲染保持
  5. 类型安全: 使用 TypeScript 泛型获得更好的类型推导

📄 依赖

  • react ^19.0.0
  • antd ^6.0.0
  • zustand ^5.0.0

📝 License

MIT

👨‍💻 Author

leafront ([email protected])

🔗 相关链接