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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sttot/api-hooks

v1.2.7

Published

在 React 中轻松且规范地定义 API 请求、一键创建钩子函数,包含状态跟踪、请求中断和请求刷新,并方便进行错误处理和批量请求与进度跟踪。

Downloads

1

Readme

api-hooks 在 React 中更优雅的定义与使用 Api 请求

在 React 中轻松且规范地定义 API 请求、一键创建钩子函数,包含状态跟踪、请求中断和请求刷新,并方便进行错误处理和批量请求与进度跟踪。


安装

本轮子基于并包含了 @sttot/axios-api,适于 React 使用,如果使用了本轮轮子就不需要额外安装 axios 和 @sttot/axios-api。

pnpm install @sttot/api-hooks

使用

可以使用 apiFactory 用指定 axios 实例创建一个 api 工厂函数:

import axios from 'axios';
import { apiFactory } from '@sttot/api-hooks';

const api = apiFactory(axios.create({}));

如果没有自定义 axios 实例的需求,也可以直接使用默认的 api 工厂函数:

import { api } from '@sttot/api-hooks';

这个 api 函数等价于 @sttot/axios-api 中使用 apiBase 创建的 api 工厂函数,具体用法请参考 @sttot/axios-api,这里只介绍 @sttot/api-hooks 扩展的功能:

创建一个钩子函数

先从最简单的 GET 请求开始,假设已经有如下的 API 定义:

const myApi = api<number, string>(
  id => ({
    method: 'GET',
    url: `https://api.sttot.com/test/${id}`,
  }),
  ({ data }) => data,
);

我们希望在一个 React 组件中使用它:有一个输入 id 的输入框,请求服务器上对应的字符串并显示,可能的话,对错误进行打印、显示加载中、对错误请求进行重试并可以中止请求。可以使用该 Api 创建一个钩子函数:

import { useState } from 'react';
const useInfo = myApi.creatrMemoHook();

export default () => {
  const [id, setId] = useState(0);
  const [result, error, loading, cancel, retry] = useInfo(id, [id]);
  return (
    <div>
      <input
        type="number"
        placeholder="查询 ID"
        onChange={({ target: { value } }) => setId(Number(value) ?? 0)}
      />
      {loading ? <button onClick={() => cancel()}>中止</button> : <></>}
      {error ? (
        <div>
          出错了: {String(error)}
          <button onClick={retry}>重试</button>
        </div>
      ) : (
        <></>
      )}
      <p>{loading ? '加载中...' : `查询结果: ${result ?? ''}`}</p>
    </div>
  );
};

createMemoHook 会创建一个钩子函数,该函数有两个参数,第一个参数接受的是 Api 的参数或者返回 Api 参数的函数;第二个参数和 useEffect 一样,是一个数组,只有数组中的变量改变,才会重新调用请求。

钩子返回一个数组,其中一共有五个对象:

  • 第一个对象是 Api 结果,在请求进行时或出错时是 undefined;
  • 第二个对象是 Api 最终抛出的结果,在请求进行时或者请求成功时是 undefined;
  • 第三个对象是一个布尔值,表示现在请求是否正在进行中;
  • 第四个对象是一个函数,用来中止请求,有一个可选参数用来指定中止原因;
  • 第五个对象是一个函数,用来重新进行请求;

注:不需要用到的对象可以不接收,例如如下写法:

const [result] = useInfo(id, [id]);
const [result, , , , retry] = useInfo(id, [id]);

注:假如有如下代码:

const [result] = useXXX(a, [b]);
useEffect(() => {
  //
}, [result, b]);

应当注意到,当 b 变化时,result 会首先变成 undefined,在请求结束后 result 又会被改变;因此 useEffect 会被调用两次而不是一次。


Reducer 钩子

有时请求 Api 并不需要一个结果,或者调用 Api 的时机并不是某个值被改变了(例如希望在点击按钮时再去查询),此时就需要使用 React 中 Reducer+Dispatch 的思想:

import { useState } from 'react';
const useInfoReducer = myApi.createReducerHook();

export default () => {
  const [id, setId] = useState(0);
  const {
    result,
    error,
    pending,
    idle,
    fullfilled,
    rejected,
    dispatch,
    cancel,
  } = useInfoReducer();
  return (
    <div>
      <input
        type="number"
        placeholder="查询 ID"
        onChange={({ target: { value } }) => setId(Number(value) ?? -1)}
      />
      <button onClick={() => dispatch(id)}>查询</button>
      {loading ? <button onClick={() => cancel()}>中止</button> : <></>}
      {error ? (
        <div>
          出错了: {String(error)}
          <button onClick={() => dispatch(id)}>重试</button>
        </div>
      ) : (
        <></>
      )}
      <p>{pending ? '加载中...' : `查询结果: ${result ?? ''}`}</p>
    </div>
  );
};

result、error、cancel 同上,对不同的部分进行解释:

  • 由于请求在一开始不会自动触发,因此会有四种状态:
    • idle 尚未执行过任何请求;
    • pending 正在执行请求;
    • fullfilled 请求成功;
    • rejected 请求失败;
  • dispatch 是用发起请求的函数,第一个参数是 Api 的参数,第二个是可选参数,Api 请求回调;

除此之外,还有两个钩子,用于做批量请求,具体使用方式类似,请参考代码注释提示:

  • createBatchReducerHook
  • createBatchMemoHook