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

@sevenvip666/react-art

v2.0.2

Published

a request template

Readme

art

一个面向 React 的请求状态库,支持 querymutation、分页、缓存、共享 store,以及对象式细粒度更新。

安装

pnpm add @sevenvip666/react-art
npm install @sevenvip666/react-art

核心特性

  • useQuery / useMutation / usePagination
  • makeQuery / makeMutation / makePagination
  • callable store:store()store(selector)
  • 对象式细粒度更新:没读到的字段更新时不触发当前组件 re-render
  • selector 订阅能力
  • 请求缓存、重新验证、轮询、重试
  • fetch / axios 双请求模式
  • sharedKey 共享 store

快速开始

useQuery

import { useQuery } from '@sevenvip666/react-art'

function UserView() {
  const { data, isLoading, query, refresh } = useQuery<
    { id: number; name: string },
    { id: number }
  >('/api/user/detail', {
    defaultBody: { id: 1 },
    loading: true
  })

  return (
    <div>
      {isLoading ? 'loading...' : data?.name}
      <button onClick={() => query({ id: 2 })}>load</button>
      <button onClick={() => refresh()}>refresh</button>
    </div>
  )
}

makeQuery + store()

import { makeQuery } from '@sevenvip666/react-art'

const userStore = makeQuery<{ name: string }, { id: number }>('/api/user/detail')

function UserView() {
  const { data, isLoading } = userStore()
  return <div>{isLoading ? 'loading...' : data?.name}</div>
}

makeQuery + store(selector)

function UserName() {
  const name = userStore((state) => state.data?.name)
  return <div>{name}</div>
}

请求定义

RequestType<TBody>

请求可以是以下三种形式:

  • string:请求地址
  • (body: TBody) => string:根据 body 生成地址
  • (body: TBody) => Promise<any>:完全自定义请求

示例:

'/api/user/detail'
(body) => `/api/user/${body.id}`
async (body) => customClient.get('/api/user', { params: body })

Hook API

useQuery<TData, TBody>(request, config?, deps?)

用于普通查询。

参数:

  • request: RequestType<TBody>:请求地址或请求函数
  • config?: HooksQueryConfig<TData, TBody>:查询配置
  • deps?: DependencyList:重新创建 store 的依赖

返回:

  • QueryStoreType<TData, TBody>

常用返回字段:

  • data?: TData
  • originData?: TData
  • body?: Partial<TBody>
  • status: 'idle' | 'loading' | 'success' | 'error'
  • isLoading
  • isSuccess
  • isError
  • error
  • lastRequestTime

常用返回方法:

  • query(body?, runConfig?)
  • querySync(body?, runConfig?)
  • refresh(config?)
  • refreshSync(config?)
  • setBody(body, replace?)
  • setData(data, replace?)
  • setStatus(status, error?)
  • setCache(data)
  • cancel(message?)
  • clear()

useMutation<TBody, TData>(request, config?, deps?)

用于提交类请求。

参数:

  • request: RequestType<TBody>
  • config?: HooksMutationConfig<TBody, TData>
  • deps?: DependencyList

返回:

  • MutationStoreType<TBody, TData>

额外方法:

  • mutate(body?, runConfig?)
  • mutateSync(body?, runConfig?)

usePagination<TData extends Array<unknown>, TBody>(request, config?, deps?)

用于分页查询或无限加载。

参数:

  • request: RequestType<TBody>
  • config?: HooksPageConfig<TData, TBody>
  • deps?: DependencyList

返回:

  • QueryPageStoreType<TData, TBody>

额外字段:

  • current
  • pageSize
  • pageTokens
  • total
  • hasNextPage
  • isLoadingNextPage
  • isErrorNextPage

额外方法:

  • query(body?, runConfig?)
  • queryByPage(pageConfig?, runConfig?)
  • queryNextPage(pageConfig?, runConfig?)

useSharedQuery(sharedKey, request, config?, deps?)

useQuery 一致,但会通过 sharedKey 复用同一个 store。

useSharedPagination(sharedKey, request, config?, deps?)

usePagination 一致,但会通过 sharedKey 复用同一个 store。

makeStore API

makeQuery<TData, TBody>(request, config?)

makeMutation<TBody, TData>(request, config?)

makePagination<TData, TBody>(request, config?)

返回可复用 store,适合:

  • 组件外创建
  • 多组件共享
  • 命令式调用

store 可直接调用:

const store = makeQuery<{ name: string }, { id: number }>('/api/user/detail')

await store.query({ id: 1 })
store.setBody({ id: 2 })
store.setData({ name: 'new name' })
store.clear()

在 React 组件中消费时使用:

  • store()
  • store(selector)

Callable Store

每个 makeQuery / makeMutation / makePagination 创建出来的 store 本身就是 React 消费入口。

store()

返回对象式视图,支持细粒度更新:

const { data, isLoading } = store()

store(selector, equalityFn?)

返回选中的值:

const data = store((state) => state.data)
const loading = store((state) => state.isLoading)

Selector API

如果你希望显式使用 selector,也可以使用这些 hook:

  • useArtSelector(store, selector, equalityFn?)
  • useQuerySelector(store, selector, equalityFn?)
  • usePaginationSelector(store, selector, equalityFn?)
  • useMutationSelector(store, selector, equalityFn?)
  • useStoreSelector(store, selector, equalityFn?)

Shared Store API

useSharedQueryStore(key, storeOrFactory, options?)

把已有 store 放进共享池,在多个组件间复用。

参数:

  • key: string
  • storeOrFactory: store | (() => store)
  • options?: { manual?: boolean }

getSharedQueryStore(key)

读取共享 store。

setSharedQueryStore(key, store)

手动写入共享 store。

clearSharedQueryStore(key)

清理指定共享 store,并调用 cancel()

clearAllSharedQueryStore()

清理全部共享 store,并调用各自的 cancel()

自动管理 Hook

useAutoQuery(store, body?, deps?)

组件挂载后自动执行 store.query(body)

useAutoMutate(store, body?, deps?)

组件挂载后自动执行 store.mutate(body)

useManagedStore(store)

把 store 注册给 Art 管理。用于配合 locale 切换后的自动刷新。

Art 全局配置

Art.setup(config?)

设置全局配置。

import { Art } from '@sevenvip666/react-art'
import axios from 'axios'

Art.setup({
  baseURL: 'https://api.example.com',
  axios: { axios },
  showErrorMessage: (res) => console.error(res.message)
})

ArtConfigOptions

基础配置

  • baseURL?: string:全局请求前缀
  • debug?: boolean
  • localCache?: boolean:是否使用本地缓存
  • cacheKeyPrefix?: string:缓存 key 前缀

fetch 模式

  • fetch?: { fetch?: typeof fetch; requestInit?: (url, method, body) => RequestInit; errorStatus?: number[] }

axios 模式

  • axios?: { axios: AxiosStatic; instance?: AxiosInstance; instanceCallback?: (instance) => void }

全局 UI 回调

  • showErrorMessage?: (res) => void
  • showSuccessMessage?: (res) => void
  • startLoading?: () => void
  • endLoading?: () => void

响应转换

  • convertRes?: (res, request?) => UseResult | Promise<UseResult>
  • convertError?: (res, defaultResult) => Partial<UseResult>
  • convertPage?: ({ current, pageSize, nextToken }) => any
  • handleHttpError?: (error) => void
  • handleCustomHttpError?: (error) => UseResult

缓存扩展

  • setCacheData?: (key, data) => void
  • clearCacheData?: (key) => void
  • getCacheData?: (key) => CachedData | undefined

重试判断

  • checkRetry?: (res) => boolean

其他全局方法

  • Art.setBaseUrl(url)
  • Art.setCacheKeyPrefix(prefix)
  • Art.setLocale(locale?)

setLocale 会刷新当前仍被 React 管理、且已经请求过的非 mutation store。

ArtProvider

ArtProvider

import { ArtProvider } from '@sevenvip666/react-art'

<ArtProvider config={{ baseURL: '/api' }} locale="zh-CN">
  <App />
</ArtProvider>

参数:

  • config?: ArtConfigOptions
  • locale?: string

配置项说明

FetchConfig<TData, TBody>

所有 query / mutation / pagination 共用的基础配置。

  • status?: boolean:是否自动维护 status
  • loading?: boolean:是否触发全局 loading
  • startLoading?: () => void
  • endLoading?: () => void
  • defaultBody?: Partial<TBody> | (() => Partial<TBody>)
  • method?: Method
  • postBody?: (body) => any:发请求前转换 body
  • showMessage?: boolean
  • showErrorMessage?: boolean
  • showSuccessMessage?: boolean
  • successMessage?: string
  • errorMessage?: string
  • disableCompare?: boolean
  • onSuccess?: (data, cache, isSame?) => void
  • customConfig?: object | ((body) => object):透传给 fetch/axios
  • onError?: (res) => void
  • onComplete?: (res) => void
  • convertRes?: (res, request) => UseResult | Promise<UseResult>
  • postData?: (data) => TData
  • loadingDelayMs?: number
  • debounceMs?: number | (() => number)
  • throttleMs?: number | (() => number)
  • retry?: number
  • checkRetry?: (res) => boolean
  • retryInterval?: number
  • timeout?: number

BaseQueryConfig<TData, TBody>

query / pagination 专用配置。

  • autoClear?: boolean
  • cacheType?: 'default' | 'memory'
  • cache?: boolean | string | ((body) => string | boolean)
  • cacheKeys?: string[] | ((body) => Array<string | number | undefined>)
  • cacheLoading?: boolean
  • cacheStatus?: boolean
  • cacheTime?: number
  • revalidate?: number
  • initialData?: TData | (() => TData)
  • setInitialData?: TData | (() => TData)
  • placeholderData?: TData | (() => TData)
  • initializeCache?: boolean

FetchRunConfig

运行时配置。

  • refresh?: boolean
  • replaceBody?: boolean
  • status?: boolean
  • loading?: boolean
  • whenNoData?: boolean

FetchPageRunConfig

分页运行时配置。

  • 继承 FetchRunConfig
  • pageSize?: number
  • infinite?: boolean

HooksBaseConfig

hook 层额外配置。

  • sharedKey?: string
  • manual?: boolean
  • pollingIntervalMs?: number
  • refreshOnWindowFocus?: boolean
  • refreshOnWindowFocusMode?: 'run' | 'refresh'
  • refreshOnWindowFocusTimespanMs?: number

StorePageConfig

分页配置。

  • defaultNextToken?: string
  • defaultHasNextPage?: boolean
  • total?: number
  • current?: number
  • pageSize?: number
  • infinite?: boolean
  • getNextToken?: (res) => string
  • hasNextPage?: (res) => boolean

请求返回值

UseResult<TData>

  • success: boolean
  • data?: TData
  • message?: string
  • code?: string
  • status?: number
  • total?: number
  • isCancel?: boolean
  • other?: any
  • isSame?: boolean

错误处理工具

  • handleFetchError
  • handleAxiosError

推荐使用方式

推荐

  • 组件内直接请求:useQuery / useMutation / usePagination
  • 组件外创建 store:makeQuery / makeMutation / makePagination + store()

可选增强

  • store(selector)useQuerySelector(...)

这条路径更显式,也更适合作为复杂场景或 React Compiler 兼容增强方案。

License

MIT