From 4ff6fd8422ec55980a2dcb4dd8e9559610575edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=BD=E9=BE=99?= Date: Tue, 21 Apr 2020 23:29:55 +0800 Subject: [PATCH] chore: upgrade to ahooks & delete unused hooks --- .umirc.js | 10 +- CONTRIBUTING.MD | 6 +- README.md | 29 +- README.zh-CN.md | 28 +- docs/docs/faq.en-US.md | 12 +- docs/docs/faq.zh-CN.md | 12 +- docs/docs/getting-started.en-US.md | 18 +- docs/docs/getting-started.zh-CN.md | 18 +- docs/index.en-US.md | 12 +- docs/index.zh-CN.md | 10 +- now.json | 3 - package-lock.json | 2 +- package.json | 6 +- packages/hooks/package.json | 11 +- packages/hooks/src/index.ts | 15 +- .../hooks/src/useAPI/__tests__/index.test.ts | 26 -- packages/hooks/src/useAPI/demo/demo1.tsx | 21 - packages/hooks/src/useAPI/demo/demo2.tsx | 27 -- packages/hooks/src/useAPI/demo/demo3.tsx | 29 -- packages/hooks/src/useAPI/demo/demo4.tsx | 35 -- packages/hooks/src/useAPI/index.en-US.md | 46 -- packages/hooks/src/useAPI/index.ts | 36 -- packages/hooks/src/useAPI/index.zh-CN.md | 44 -- .../src/useAntdTable/__tests__/index.test.ts | 303 ------------- .../hooks/src/useAntdTable/demo/demo1.tsx | 59 --- .../hooks/src/useAntdTable/demo/demo2.tsx | 76 ---- .../hooks/src/useAntdTable/demo/demo3.tsx | 96 ---- .../hooks/src/useAntdTable/demo/demo4.tsx | 140 ------ .../hooks/src/useAntdTable/demo/demo5.tsx | 135 ------ .../hooks/src/useAntdTable/index.en-US.md | 151 ------- packages/hooks/src/useAntdTable/index.ts | 421 ------------------ .../hooks/src/useAntdTable/index.zh-CN.md | 152 ------- packages/hooks/src/useAntdTable/typings.ts | 45 -- .../src/useAsync/__tests__/index.test.ts | 263 ----------- packages/hooks/src/useAsync/demo/demo1.tsx | 34 -- packages/hooks/src/useAsync/demo/demo2.tsx | 28 -- packages/hooks/src/useAsync/demo/demo3.tsx | 34 -- packages/hooks/src/useAsync/demo/demo4.tsx | 44 -- packages/hooks/src/useAsync/index.en-US.md | 84 ---- packages/hooks/src/useAsync/index.ts | 229 ---------- packages/hooks/src/useAsync/index.zh-CN.md | 88 ---- packages/hooks/src/useBoolean/demo/demo1.tsx | 2 +- .../hooks/src/useClickAway/demo/demo1.tsx | 2 +- .../hooks/src/useClickAway/demo/demo2.tsx | 2 +- .../src/useControllableValue/demo/demo1.tsx | 2 +- .../src/useControllableValue/demo/demo2.tsx | 2 +- .../src/useControllableValue/demo/demo3.tsx | 2 +- packages/hooks/src/useCounter/demo/demo1.tsx | 2 +- packages/hooks/src/useCreation/demo/demo1.tsx | 2 +- packages/hooks/src/useDebounce/demo/demo1.tsx | 2 +- .../hooks/src/useDebounceFn/demo/demo1.tsx | 2 +- .../hooks/src/useDebounceFn/demo/demo2.tsx | 2 +- .../src/useDocumentVisibility/demo/demo1.tsx | 2 +- packages/hooks/src/useDrop/demo/demo1.tsx | 2 +- .../hooks/src/useDynamicList/demo/demo1.tsx | 2 +- .../hooks/src/useDynamicList/demo/demo2.tsx | 2 +- .../hooks/src/useDynamicList/demo/demo3.tsx | 2 +- .../hooks/src/useEventEmitter/demo/demo1.tsx | 4 +- .../hooks/src/useEventTarget/demo/demo1.tsx | 2 +- .../hooks/src/useEventTarget/demo/demo2.tsx | 2 +- .../hooks/src/useFormTable/demo/demo1.tsx | 8 +- .../hooks/src/useFormTable/demo/demo2.tsx | 8 +- .../hooks/src/useFormTable/demo/demo3.tsx | 4 +- .../hooks/src/useFormTable/demo/demo4.tsx | 4 +- .../hooks/src/useFormTable/demo/demo5.tsx | 4 +- packages/hooks/src/useFormTable/index.ts | 4 +- .../hooks/src/useFullscreen/demo/demo1.tsx | 2 +- .../hooks/src/useFullscreen/demo/demo2.tsx | 2 +- .../hooks/src/useHistoryTravel/demo/demo1.tsx | 2 +- packages/hooks/src/useHover/demo/demo1.tsx | 2 +- packages/hooks/src/useHover/demo/demo2.tsx | 2 +- .../hooks/src/useInViewport/demo/demo1.tsx | 2 +- .../hooks/src/useInViewport/demo/demo2.tsx | 2 +- packages/hooks/src/useKeyPress/demo/demo1.tsx | 2 +- packages/hooks/src/useKeyPress/demo/demo2.tsx | 2 +- packages/hooks/src/useKeyPress/demo/demo3.tsx | 2 +- packages/hooks/src/useKeyPress/demo/demo4.tsx | 2 +- packages/hooks/src/useKeyPress/demo/demo5.tsx | 2 +- .../src/useLoadMore/__tests__/index.test.ts | 310 ------------- packages/hooks/src/useLoadMore/demo/demo1.tsx | 125 ------ packages/hooks/src/useLoadMore/demo/demo2.tsx | 127 ------ packages/hooks/src/useLoadMore/demo/demo3.tsx | 137 ------ packages/hooks/src/useLoadMore/demo/demo4.tsx | 142 ------ packages/hooks/src/useLoadMore/demo/demo5.tsx | 133 ------ packages/hooks/src/useLoadMore/index.en-US.md | 107 ----- packages/hooks/src/useLoadMore/index.ts | 172 ------- packages/hooks/src/useLoadMore/index.zh-CN.md | 106 ----- .../src/useLocalStorageState/demo/demo1.tsx | 2 +- .../src/useLocalStorageState/demo/demo2.tsx | 2 +- .../src/useLocalStorageState/demo/demo3.tsx | 2 +- packages/hooks/src/useMap/demo/demo1.tsx | 2 +- packages/hooks/src/useMount/demo/demo1.tsx | 2 +- packages/hooks/src/useMouse/demo/demo1.tsx | 2 +- .../src/usePagination/__tests__/index.test.ts | 182 -------- .../hooks/src/usePagination/demo/demo1.tsx | 65 --- .../hooks/src/usePagination/demo/demo2.tsx | 72 --- .../hooks/src/usePagination/index.en-US.md | 74 --- packages/hooks/src/usePagination/index.ts | 158 ------- .../hooks/src/usePagination/index.zh-CN.md | 74 --- .../hooks/src/usePersistFn/demo/demo1.tsx | 2 +- packages/hooks/src/usePrevious/demo/demo1.tsx | 2 +- packages/hooks/src/usePrevious/demo/demo2.tsx | 2 +- .../hooks/src/useResponsive/demo/demo1.tsx | 2 +- packages/hooks/src/useScroll/demo/demo1.tsx | 2 +- packages/hooks/src/useScroll/demo/demo2.tsx | 2 +- .../src/useSearch/__tests__/index.test.ts | 129 ------ packages/hooks/src/useSearch/demo/demo1.tsx | 38 -- packages/hooks/src/useSearch/demo/demo2.tsx | 56 --- packages/hooks/src/useSearch/index.en-US.md | 77 ---- packages/hooks/src/useSearch/index.ts | 84 ---- packages/hooks/src/useSearch/index.zh-CN.md | 77 ---- .../hooks/src/useSelections/demo/demo1.tsx | 2 +- .../src/useSessionStorageState/demo/demo1.tsx | 2 +- .../src/useSessionStorageState/demo/demo2.tsx | 2 +- .../src/useSessionStorageState/demo/demo3.tsx | 2 +- packages/hooks/src/useSet/demo/demo1.tsx | 2 +- packages/hooks/src/useSize/demo/demo1.tsx | 2 +- packages/hooks/src/useSize/demo/demo2.tsx | 2 +- packages/hooks/src/useSize/demo/demo3.tsx | 2 +- .../hooks/src/useTextSelection/demo/demo1.tsx | 2 +- .../hooks/src/useTextSelection/demo/demo2.tsx | 2 +- .../hooks/src/useTextSelection/demo/demo3.tsx | 2 +- .../hooks/src/useTextSelection/demo/demo4.tsx | 2 +- packages/hooks/src/useThrottle/demo/demo1.tsx | 2 +- .../hooks/src/useThrottleFn/demo/demo1.tsx | 2 +- .../hooks/src/useThrottleFn/demo/demo2.tsx | 2 +- packages/hooks/src/useToggle/demo/demo1.tsx | 2 +- packages/hooks/src/useToggle/demo/demo2.tsx | 2 +- packages/hooks/src/useUnmount/demo/demo1.tsx | 2 +- packages/hooks/src/useUpdate/demo/demo1.tsx | 2 +- .../hooks/src/useUpdateEffect/demo/demo1.tsx | 2 +- .../src/useUpdateLayoutEffect/demo/demo1.tsx | 2 +- .../hooks/src/useVirtualList/demo/demo1.tsx | 2 +- .../hooks/src/useVirtualList/demo/demo2.tsx | 2 +- packages/use-request/demo/axios.tsx | 2 +- packages/use-request/demo/cacheKey.tsx | 2 +- packages/use-request/demo/concurrent.tsx | 2 +- packages/use-request/demo/debounce.tsx | 2 +- packages/use-request/demo/default.tsx | 2 +- packages/use-request/demo/loadMore-1.tsx | 2 +- packages/use-request/demo/loadMore-2.tsx | 4 +- packages/use-request/demo/loadingDelay.tsx | 2 +- packages/use-request/demo/manual.tsx | 2 +- packages/use-request/demo/mutate.tsx | 2 +- packages/use-request/demo/pagination-1.tsx | 2 +- packages/use-request/demo/pagination-antd.tsx | 2 +- .../use-request/demo/pagination-cache.tsx | 2 +- packages/use-request/demo/polling.tsx | 2 +- packages/use-request/demo/preload.tsx | 2 +- packages/use-request/demo/refreshDeps.tsx | 2 +- .../use-request/demo/refreshOnWindowFocus.tsx | 2 +- packages/use-request/demo/throttle.tsx | 2 +- packages/use-request/demo/umiRequest.tsx | 2 +- packages/use-request/index.en-US.md | 4 +- packages/use-request/index.zh-CN.md | 6 +- packages/use-request/package.json | 12 +- 156 files changed, 197 insertions(+), 5314 deletions(-) delete mode 100644 packages/hooks/src/useAPI/__tests__/index.test.ts delete mode 100644 packages/hooks/src/useAPI/demo/demo1.tsx delete mode 100644 packages/hooks/src/useAPI/demo/demo2.tsx delete mode 100644 packages/hooks/src/useAPI/demo/demo3.tsx delete mode 100644 packages/hooks/src/useAPI/demo/demo4.tsx delete mode 100644 packages/hooks/src/useAPI/index.en-US.md delete mode 100644 packages/hooks/src/useAPI/index.ts delete mode 100644 packages/hooks/src/useAPI/index.zh-CN.md delete mode 100644 packages/hooks/src/useAntdTable/__tests__/index.test.ts delete mode 100644 packages/hooks/src/useAntdTable/demo/demo1.tsx delete mode 100644 packages/hooks/src/useAntdTable/demo/demo2.tsx delete mode 100644 packages/hooks/src/useAntdTable/demo/demo3.tsx delete mode 100644 packages/hooks/src/useAntdTable/demo/demo4.tsx delete mode 100644 packages/hooks/src/useAntdTable/demo/demo5.tsx delete mode 100644 packages/hooks/src/useAntdTable/index.en-US.md delete mode 100644 packages/hooks/src/useAntdTable/index.ts delete mode 100644 packages/hooks/src/useAntdTable/index.zh-CN.md delete mode 100644 packages/hooks/src/useAntdTable/typings.ts delete mode 100644 packages/hooks/src/useAsync/__tests__/index.test.ts delete mode 100644 packages/hooks/src/useAsync/demo/demo1.tsx delete mode 100644 packages/hooks/src/useAsync/demo/demo2.tsx delete mode 100644 packages/hooks/src/useAsync/demo/demo3.tsx delete mode 100644 packages/hooks/src/useAsync/demo/demo4.tsx delete mode 100644 packages/hooks/src/useAsync/index.en-US.md delete mode 100644 packages/hooks/src/useAsync/index.ts delete mode 100644 packages/hooks/src/useAsync/index.zh-CN.md delete mode 100644 packages/hooks/src/useLoadMore/__tests__/index.test.ts delete mode 100644 packages/hooks/src/useLoadMore/demo/demo1.tsx delete mode 100644 packages/hooks/src/useLoadMore/demo/demo2.tsx delete mode 100644 packages/hooks/src/useLoadMore/demo/demo3.tsx delete mode 100644 packages/hooks/src/useLoadMore/demo/demo4.tsx delete mode 100644 packages/hooks/src/useLoadMore/demo/demo5.tsx delete mode 100644 packages/hooks/src/useLoadMore/index.en-US.md delete mode 100644 packages/hooks/src/useLoadMore/index.ts delete mode 100644 packages/hooks/src/useLoadMore/index.zh-CN.md delete mode 100644 packages/hooks/src/usePagination/__tests__/index.test.ts delete mode 100644 packages/hooks/src/usePagination/demo/demo1.tsx delete mode 100644 packages/hooks/src/usePagination/demo/demo2.tsx delete mode 100644 packages/hooks/src/usePagination/index.en-US.md delete mode 100644 packages/hooks/src/usePagination/index.ts delete mode 100644 packages/hooks/src/usePagination/index.zh-CN.md delete mode 100644 packages/hooks/src/useSearch/__tests__/index.test.ts delete mode 100644 packages/hooks/src/useSearch/demo/demo1.tsx delete mode 100644 packages/hooks/src/useSearch/demo/demo2.tsx delete mode 100644 packages/hooks/src/useSearch/index.en-US.md delete mode 100644 packages/hooks/src/useSearch/index.ts delete mode 100644 packages/hooks/src/useSearch/index.zh-CN.md diff --git a/.umirc.js b/.umirc.js index fca944c546..941d600760 100644 --- a/.umirc.js +++ b/.umirc.js @@ -8,7 +8,7 @@ export default { }, ]], mode: 'site', - title: 'Umi Hooks', + title: 'ahooks', dynamicImport: {}, manifest: {}, links: [{ rel: "manifest", href: "/asset-manifest.json" }], @@ -22,13 +22,13 @@ export default { navs: { 'zh-CN': [ null, - { title: 'GitHub', path: 'https://github.com/umijs/hooks' }, - { title: '更新日志', path: 'https://github.com/umijs/hooks/releases' }, + { title: 'GitHub', path: 'https://github.com/ice-lab/ahooks' }, + { title: '更新日志', path: 'https://github.com/ice-lab/ahooks/releases' }, ], 'en-US': [ null, - { title: 'GitHub', path: 'https://github.com/umijs/hooks' }, - { title: 'Changelog', path: 'https://github.com/umijs/hooks/releases' }, + { title: 'GitHub', path: 'https://github.com/ice-lab/ahooks' }, + { title: 'Changelog', path: 'https://github.com/ice-lab/ahooks/releases' }, ], }, headScripts: [ diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD index b5278ad594..d15172fe30 100644 --- a/CONTRIBUTING.MD +++ b/CONTRIBUTING.MD @@ -2,11 +2,11 @@ > 参考 ant design [贡献指南](https://ant.design/docs/react/contributing-cn) -这篇指南会指导你如何为 `@umijs/hooks` 贡献一份自己的力量,请在你要提 issue 或者 pull request 之前花几分钟来阅读一遍这篇指南。 +这篇指南会指导你如何为 `ahooks` 贡献一份自己的力量,请在你要提 issue 或者 pull request 之前花几分钟来阅读一遍这篇指南。 ## 透明的开发 -我们所有的工作都会放在 [GitHub](https://github.com/umijs/hooks) 上。不管是核心团队的成员还是外部贡献者的 pull request 都需要经过同样流程的 review。 +我们所有的工作都会放在 [GitHub](https://github.com/ice-lab/ahooks) 上。不管是核心团队的成员还是外部贡献者的 pull request 都需要经过同样流程的 review。 ## 分支管理 @@ -35,7 +35,7 @@ 在你 clone 代码并且使用 `npm run init` 安装完依赖后,你还可以运行下面几个常用的命令: -1. `npm start` 在本地运行 `@umijs/hooks` 网站。 +1. `npm start` 在本地运行 `ahooks` 网站。 2. `npm run test` 运行测试。 diff --git a/README.md b/README.md index 0544a3fef5..d4e7e7203b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -English | [简体中文](https://github.com/umijs/hooks/blob/master/README.zh-CN.md) +English | [简体中文](https://github.com/ice-lab/ahooks/blob/master/README.zh-CN.md) -# @umijs/hooks +# ahooks React Hooks Library. @@ -18,27 +18,22 @@ React Hooks Library. * Contains a wealth of basic Hooks. * Written in TypeScript with predictable static types. -## 📣 Explain - -**You can use umi hooks anywhere, with any component library.** -Although our examples are based on ant design, it does not mean that our Hooks can only be used with ant design. - ## 📦 Install ``` -npm i @umijs/hooks --save +npm i ahooks --save ``` ## 🔨 Usage ``` -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; ``` ## 🖥 Development ``` -$ git clone git@github.com:umijs/hooks.git +$ git clone git@github.com:ice-lab/ahooks.git $ cd hooks $ npm run init $ npm start @@ -47,19 +42,19 @@ Open your browser and visit http://127.0.0.1:8001 , see more at Development. ## 🤝 Contributing -We welcome all contributions, please read our [CONTRIBUTING.MD](https://github.com/umijs/hooks/blob/master/CONTRIBUTING.MD) first, let's build a better hooks library together. +We welcome all contributions, please read our [CONTRIBUTING.MD](https://github.com/ice-lab/ahooks/blob/master/CONTRIBUTING.MD) first, let's build a better hooks library together. ## 👥 Discuss - + ## ✅ License -[MIT](https://github.com/umijs/umi/blob/master/LICENSE) +[MIT](https://github.com/ice-lab/ahooks/blob/master/LICENSE) -[1]: https://www.npmjs.com/package/@umijs/hooks -[2]: https://npmjs.org/package/@umijs/hooks +[1]: https://www.npmjs.com/package/ahooks +[2]: https://npmjs.org/package/ahooks -[image-1]: https://img.shields.io/npm/v/@umijs/hooks.svg?style=flat -[image-2]: https://img.shields.io/npm/dm/@umijs/hooks.svg?style=flat +[image-1]: https://img.shields.io/npm/v/ahooks.svg?style=flat +[image-2]: https://img.shields.io/npm/dm/ahooks.svg?style=flat diff --git a/README.zh-CN.md b/README.zh-CN.md index a056f762d9..981b9e084d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,6 +1,6 @@ -[English](https://github.com/umijs/hooks/blob/master/README.md) | 简体中文 +[English](https://github.com/ice-lab/ahooks/blob/master/README.md) | 简体中文 -# @umijs/hooks +# ahooks React Hooks Library. @@ -18,28 +18,22 @@ React Hooks Library. * 包含丰富的基础 Hooks。 * 使用 TypeScript 构建,提供完整的类型定义文件。 -## 📣 说明 - -**你可以将 umi hooks 使用在任何地方,和任意组件库搭配使用。** -虽然我们的代码示例都是基于 ant design 的,但是并不代表我们的 Hooks 只能和 ant design 配合使用。 - - ## 📦 安装 ``` -npm i @umijs/hooks --save +npm i ahooks --save ``` ## 🔨使用 ``` -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; ``` ## 🖥 开发 ``` -$ git clone git@github.com:umijs/hooks.git +$ git clone git@github.com:ice-lab/ahooks.git $ cd hooks $ npm run init $ npm start @@ -48,7 +42,7 @@ $ npm start ## 🤝 贡献 -我们欢迎所有人参与共建,请参考[CONTRIBUTING.MD](https://github.com/umijs/hooks/blob/master/CONTRIBUTING.MD) +我们欢迎所有人参与共建,请参考[CONTRIBUTING.MD](https://github.com/ice-lab/ahooks/blob/master/CONTRIBUTING.MD) ## 👥 讨论 @@ -56,10 +50,10 @@ $ npm start ## ✅ License -[MIT](https://github.com/umijs/umi/blob/master/LICENSE) +[MIT](https://github.com/ice-lab/ahooks/blob/master/LICENSE) -[1]: https://www.npmjs.com/package/@umijs/hooks -[2]: https://npmjs.org/package/@umijs/hooks +[1]: https://www.npmjs.com/package/ahooks +[2]: https://npmjs.org/package/ahooks -[image-1]: https://img.shields.io/npm/v/@umijs/hooks.svg?style=flat -[image-2]: https://img.shields.io/npm/dm/@umijs/hooks.svg?style=flat +[image-1]: https://img.shields.io/npm/v/ahooks.svg?style=flat +[image-2]: https://img.shields.io/npm/dm/ahooks.svg?style=flat diff --git a/docs/docs/faq.en-US.md b/docs/docs/faq.en-US.md index 1052dfedba..4a467565b8 100644 --- a/docs/docs/faq.en-US.md +++ b/docs/docs/faq.en-US.md @@ -1,12 +1,12 @@ # FAQ -Here are the frequently asked questions about Umi Hooks, you should look up before you ask in the community or create a new issue. +Here are the frequently asked questions about ahooks, you should look up before you ask in the community or create a new issue. -### Can I only use Umi Hooks in ant design? +### Can I only use ahooks in ant design? -You can use umi hooks anywhere, with any component library.Although our examples are based on ant design, it does not mean that our Hooks can only be used with ant design. +You can use ahooks anywhere, with any component library.Although our examples are based on ant design, it does not mean that our Hooks can only be used with ant design. -### When I use Umi Hooks, I get an error `regeneratorRuntime is not defined`, how can I solve it? +### When I use ahooks, I get an error `regeneratorRuntime is not defined`, how can I solve it? ``` // install regenerator-runtime @@ -16,9 +16,9 @@ npm i regenerator-runtime --save import "regenerator-runtime/runtime"; ``` -### I only want to use `useRquest`, but I have to install the entire `@umijs/hooks`? +### I only want to use `useRquest`, but I have to install the entire `ahooks`? -No, `useRequest` is a independent package, can be used by installing `@umijs/use-request` separately. +No, `useRequest` is a independent package, can be used by installing `@ahooksjs/use-request` separately. ### I only want to use one or two of them, but all the hooks are compiled after the project is compiled. diff --git a/docs/docs/faq.zh-CN.md b/docs/docs/faq.zh-CN.md index d9e286834f..332feef0ef 100644 --- a/docs/docs/faq.zh-CN.md +++ b/docs/docs/faq.zh-CN.md @@ -1,13 +1,13 @@ # FAQ -以下整理了一些 Umi Hooks 社区常见的问题和官方答复,在提问之前建议找找有没有类似的问题。 +以下整理了一些 ahooks 社区常见的问题和官方答复,在提问之前建议找找有没有类似的问题。 -### 我只能在 ant design 中使用 Umi Hooks 吗? +### 我只能在 ant design 中使用 ahooks 吗? -你可以将 umi hooks 使用在任何地方,和任意组件库搭配使用。虽然我们的代码示例都是基于 ant design 的,但是并不代表我们的 Hooks 只能和 ant design 配合使用。 +你可以将 ahooks 使用在任何地方,和任意组件库搭配使用。虽然我们的代码示例都是基于 ant design 的,但是并不代表我们的 Hooks 只能和 ant design 配合使用。 -### 当我使用 Umi Hooks 时,报错 `regeneratorRuntime is not defined`,如何解决? +### 当我使用 ahooks 时,报错 `regeneratorRuntime is not defined`,如何解决? ``` // 安装 regenerator-runtime @@ -17,9 +17,9 @@ npm i regenerator-runtime --save import "regenerator-runtime/runtime"; ``` -### 我只想使用 `useRquest`, 但似乎我必须安装整个 `@umijs/hooks`? +### 我只想使用 `useRquest`, 但似乎我必须安装整个 `ahooks`? -不是的,`useRequest` 在独立包中,可以单独通过安装 `@umijs/use-request` 来使用。 +不是的,`useRequest` 在独立包中,可以单独通过安装 `@ahooksjs/use-request` 来使用。 ### 我只想用其中一两个 Hooks,但是项目编译后所有的 Hooks 都编译进去了。 diff --git a/docs/docs/getting-started.en-US.md b/docs/docs/getting-started.en-US.md index dc52a39f61..2118566cfe 100644 --- a/docs/docs/getting-started.en-US.md +++ b/docs/docs/getting-started.en-US.md @@ -7,14 +7,14 @@ nav: # Getting Started -Umi Hooks is a React Hooks library dedicated to providing commonly used and high quality Hooks. +ahooks is a React Hooks library dedicated to providing commonly used and high quality Hooks. > Before start, you need to know the basic usage of React and React Hooks. Follow the [link](https://reactjs.org/docs/hooks-intro.html) to learn the official React Hooks documentation. ## First Example -Here is a simple codesandbox example to show the usage of Umi Hooks. +Here is a simple codesandbox example to show the usage of ahooks. @@ -23,13 +23,13 @@ Here is a simple codesandbox example to show the usage of Umi Hooks. Visit https://codesandbox.io/s/umi-hooks-template-i8jqc to create a codesandbox. Don't forget to press the save button. -### 2. Using Umi Hooks +### 2. Using ahooks -Replace the content of App.js with the following code, use the [useToggle](/state/use-toggle) of Umi Hooks. +Replace the content of App.js with the following code, use the [useToggle](/state/use-toggle) of ahooks. ```javascript import React from "react"; -import { useToggle } from "@umijs/hooks"; +import { useToggle } from "ahooks"; export default () => { const { state, toggle } = useToggle(); @@ -54,13 +54,13 @@ You can look up Hooks in the side menu like useRequest, useHover etc. Our docume we can import individual Hooks on demand。 ```javascript -import useToggle from '@umijs/hooks/es/useToggle'; +import useToggle from 'ahooks/es/useToggle'; ``` -> Note: Umi Hooks supports ES6 tree shaking, so `import { useToggle } from '@umijs/hooks'` will drop the js code you don't use too. +> Note: ahooks supports ES6 tree shaking, so `import { useToggle } from 'ahooks'` will drop the js code you don't use too. -We strongly recommend using [babel-plugin-import](https://github.com/ant-design/babel-plugin-import), which can convert the following code to the `import useToggle from '@umijs/hooks/es/useToggle'` way: +We strongly recommend using [babel-plugin-import](https://github.com/ant-design/babel-plugin-import), which can convert the following code to the `import useToggle from 'ahooks/es/useToggle'` way: ```javascript -import { useToggle } from '@umijs/hooks'; +import { useToggle } from 'ahooks'; ``` diff --git a/docs/docs/getting-started.zh-CN.md b/docs/docs/getting-started.zh-CN.md index da06615b0b..2b39deec65 100644 --- a/docs/docs/getting-started.zh-CN.md +++ b/docs/docs/getting-started.zh-CN.md @@ -7,13 +7,13 @@ nav: # 快速上手 -Umi Hooks 是一个 React Hooks 库,致力提供常用且高质量的 Hooks。 +ahooks 是一个 React Hooks 库,致力提供常用且高质量的 Hooks。 > 在开始之前,你需要掌握 React 及 React Hooks 基础用法。访问[链接](https://zh-hans.reactjs.org/docs/hooks-intro.html)学习 React Hooks 官方文档。 ## 第一个例子 -这是一个最简单的 Umi Hooks 的在线 codesandbox 演示。 +这是一个最简单的 ahooks 的在线 codesandbox 演示。 @@ -21,13 +21,13 @@ Umi Hooks 是一个 React Hooks 库,致力提供常用且高质量的 Hooks。 访问 https://codesandbox.io/s/umi-hooks-template-i8jqc 创建一个 codesandbox 的在线示例,别忘了保存以创建一个新的实例。 -### 2. 使用 Umi Hooks +### 2. 使用 ahooks -直接用下面的代码替换 App.js 的内容,使用 Umi Hooks 中的 [useToggle](/zh-CN/state/use-toggle)。 +直接用下面的代码替换 App.js 的内容,使用 ahooks 中的 [useToggle](/zh-CN/state/use-toggle)。 ```javascript import React from "react"; -import { useToggle } from "@umijs/hooks"; +import { useToggle } from "ahooks"; export default () => { const { state, toggle } = useToggle(); @@ -53,15 +53,15 @@ export default () => { 可以通过以下的写法来按需加载 Hooks。 ```javascript -import useToggle from '@umijs/hooks/es/useToggle'; +import useToggle from 'ahooks/es/useToggle'; ``` -> 注意:Umi Hooks 默认支持基于 ES module 的 tree shaking,对于 js 部分,直接引入 `import { useToggle } from '@umijs/hooks'` 也会有按需加载的效果。 +> 注意:ahooks 默认支持基于 ES module 的 tree shaking,对于 js 部分,直接引入 `import { useToggle } from 'ahooks'` 也会有按需加载的效果。 如果你使用了 babel,那么可以使用 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 来进行按需加载,加入这个插件后。你可以仍然这么写: ```javascript -import { useToggle } from '@umijs/hooks'; +import { useToggle } from 'ahooks'; ``` -插件会帮你转换成 `@umijs/hooks/es/useToggle` 的写法。 +插件会帮你转换成 `ahooks/es/useToggle` 的写法。 diff --git a/docs/index.en-US.md b/docs/index.en-US.md index 4021140e0b..63217c7624 100644 --- a/docs/index.en-US.md +++ b/docs/index.en-US.md @@ -1,7 +1,7 @@ --- -title: Umi Hooks - React Hooks Library +title: ahooks - React Hooks Library hero: - title: Umi Hooks + title: ahooks desc: Born for React Hooks actions: - text: Getting Started @@ -9,7 +9,7 @@ hero: features: - icon: https://gw.alipayobjects.com/zos/bmw-prod/813f5ed9-6bc4-43d4-9f74-ec81ecf35733/k7htg6n4_w144_h144.png title: Rich Collection - desc: Umi Hooks contains a large set of essential react hooks, with demos and examples for each one of them. + desc: ahooks contains a large set of essential react hooks, with demos and examples for each one of them. - icon: https://gw.alipayobjects.com/zos/bmw-prod/7659205c-6637-4fa2-8529-d32e5818304b/k7htflfb_w144_h144.png title: Detailed Tutorial desc: Providing tutorials about using hooks in practice. An all-in-one place to learn for pro coders and newcomers. @@ -23,12 +23,12 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by [du ```bash // Install dependency -npm i @umijs/hooks --save +npm i ahooks --save // Use Hooks -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; ``` ## 👥 Feedback - + diff --git a/docs/index.zh-CN.md b/docs/index.zh-CN.md index 436b0e16ef..19c7296807 100644 --- a/docs/index.zh-CN.md +++ b/docs/index.zh-CN.md @@ -1,7 +1,7 @@ --- -title: Umi Hooks - React Hooks Library +title: ahooks - React Hooks Library hero: - title: Umi Hooks + title: ahooks desc: 为 React Hooks 而生 actions: - text: 快速上手 @@ -23,12 +23,12 @@ footer: Open-source MIT Licensed | Copyright © 2019-present
Powered by [du ```bash // 安装依赖 -npm i @umijs/hooks --save +npm i ahooks --save // 使用 Hooks -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; ``` ## 👥 反馈与共建 - + diff --git a/now.json b/now.json index 1c13e820bc..1ecc42dcd2 100644 --- a/now.json +++ b/now.json @@ -18,9 +18,6 @@ { "handle": "filesystem" }, { "src": "/.*", "dest": "/index.html" } ], - "github": { - "enabled": false - }, "alias": [ "hooks.umijs.org" ] diff --git a/package-lock.json b/package-lock.json index 76f40b14a6..4ffd6909c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "@umijs/hooks", + "name": "ahooks", "requires": true, "lockfileVersion": 1, "dependencies": { diff --git a/package.json b/package.json index 622f1a9b9e..9d8a4bc2bf 100755 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "@umijs/hooks", + "name": "ahooks", "private": true, "repository": { "type": "git", - "url": "git+https://github.com/umijs/hooks.git" + "url": "git+https://github.com/ice-lab/ahooks.git" }, "scripts": { "init": "rm -rf node_modules && npm install && npm run clean && npm run bootstrap && npm run build", @@ -11,7 +11,7 @@ "dev": "dumi dev", "bootstrap": "lerna bootstrap", "clean": "lerna clean --yes", - "compile": "lerna run --scope @umijs/use-request compile && lerna run --scope @umijs/hooks compile", + "compile": "lerna run --scope @ahooksjs/use-request compile && lerna run --scope ahooks compile", "build": "node ./scripts/clean-old-build.js && father build && npm run compile && node ./scripts/build-wind-up.js", "test": "father test", "test:watch": "father test --watch", diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 84feb15539..0baa6b6dba 100755 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,8 +1,9 @@ { - "name": "@umijs/hooks", - "version": "1.9.2", + "name": "ahooks", + "version": "0.1.0", "description": "react hooks library", "keywords": [ + "ahooks", "umi hooks", "react hooks" ], @@ -16,8 +17,8 @@ "publishConfig": { "registry": "https://registry.npmjs.com/" }, - "repository": "https://github.com/umijs/hooks", - "homepage": "https://github.com/umijs/hooks", + "repository": "https://github.com/ice-lab/ahooks", + "homepage": "https://github.com/ice-lab/ahooks", "scripts": { "compile": "tsc --declarationDir lib && tsc --declarationDir es" }, @@ -28,7 +29,7 @@ "package.json" ], "dependencies": { - "@umijs/use-request": "^1.4.2", + "@ahooksjs/use-request": "^0.1.0", "intersection-observer": "^0.7.0", "lodash.isequal": "^4.5.0", "resize-observer-polyfill": "^1.5.1", diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 0a68838a7c..47acaa6bee 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -1,9 +1,4 @@ -import useRequest from '@umijs/use-request'; -import useAntdTable from './useAntdTable'; -import useAPI, { configRequest } from './useAPI'; -import useAsync from './useAsync'; -import useLoadMore from './useLoadMore'; -import useSearch from './useSearch'; +import useRequest from '@ahooksjs/use-request'; import useControllableValue from './useControllableValue'; import useDynamicList from './useDynamicList'; import useEventEmitter from './useEventEmitter'; @@ -14,7 +9,6 @@ import useLocalStorageState from './useLocalStorageState'; import useSessionStorageState from './useSessionStorageState'; import useUpdateEffect from './useUpdateEffect'; import useUpdateLayoutEffect from './useUpdateLayoutEffect'; -import usePagination from './usePagination'; import useBoolean from './useBoolean'; import useToggle from './useToggle'; import useDocumentVisibility from './useDocumentVisibility'; @@ -54,11 +48,6 @@ const useControlledValue: typeof useControllableValue = function (...args) { }; export { - useAntdTable, - useAPI, - useAsync, - useLoadMore, - useSearch, useControlledValue, useControllableValue, useDynamicList, @@ -69,10 +58,8 @@ export { useSessionStorageState, useSize, configResponsive, - configRequest, useUpdateEffect, useUpdateLayoutEffect, - usePagination, useBoolean, useToggle, useDocumentVisibility, diff --git a/packages/hooks/src/useAPI/__tests__/index.test.ts b/packages/hooks/src/useAPI/__tests__/index.test.ts deleted file mode 100644 index 031d04f5bf..0000000000 --- a/packages/hooks/src/useAPI/__tests__/index.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -// import { renderHook, act } from '@testing-library/react-hooks'; -import useAPI from '../index'; - -describe('useAPI', () => { - it('should be defined', () => { - expect(useAPI).toBeDefined(); - }); - - let hook: any; - - // it('should fetch data', async () => { - // act(() => { - // hook = renderHook(props => useAPI(props), { - // initialProps: { - // url: - // 'https://gw.alipayobjects.com/os/basement_prod/b17023d5-6260-4e4f-bd91-a78802855c2a.json', - // }, - // }); - // }); - // expect(hook.result.current.loading).toBe(true); - // await hook.waitForNextUpdate(); - // expect(hook.result.current.data.name).toBe('troy'); - // expect(hook.result.current.loading).toBe(false); - // hook.unmount(); - // }); -}); diff --git a/packages/hooks/src/useAPI/demo/demo1.tsx b/packages/hooks/src/useAPI/demo/demo1.tsx deleted file mode 100644 index 0df69b9ccf..0000000000 --- a/packages/hooks/src/useAPI/demo/demo1.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * title: Default usage - * desc: The request will be sent after the component mount. - * - * title.zh-CN: 默认用法 - * desc.zh-CN: 组件加载时立即执行 - */ - -import { useAPI } from '@umijs/hooks'; -import { Spin } from 'antd'; -import React from 'react'; - -export default () => { - const { data, loading } = useAPI({ url: 'https://helloacm.com/api/random/?n=8&x=4' }); - - return ( - -
ID: {data}
-
- ); -}; diff --git a/packages/hooks/src/useAPI/demo/demo2.tsx b/packages/hooks/src/useAPI/demo/demo2.tsx deleted file mode 100644 index b26cc0cdde..0000000000 --- a/packages/hooks/src/useAPI/demo/demo2.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/** - * title: Sending request manually - * desc: Sending the request only when the "run" function is called. - * - * title.zh-CN: 手动触发执行 - * desc.zh-CN: 手动发送请求,只有当 run 方法被调用时请求才会发出。 - */ - -import { Button, Spin } from 'antd'; -import React from 'react'; -import { useAPI } from '@umijs/hooks'; - -export default () => { - const { data, loading, run } = useAPI({ - url: 'https://helloacm.com/api/random/?n=8&x=4', - manual: true, - }); - - return ( - <> - ID: {data} - - - ); -}; diff --git a/packages/hooks/src/useAPI/demo/demo3.tsx b/packages/hooks/src/useAPI/demo/demo3.tsx deleted file mode 100644 index 879bb4674f..0000000000 --- a/packages/hooks/src/useAPI/demo/demo3.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/** - * title: Polling - * desc: The request will be sent every 3 seconds, the timer will start running only if the last request has been received. - * - * title.zh-CN: 轮询 - * desc.zh-CN: 每三秒进行一次请求,将在上次请求返回后开始计时。 - */ - -import { Button, Spin } from 'antd'; -import React from 'react'; -import { useAPI } from '@umijs/hooks'; - -export default () => { - const { data, loading, timer } = useAPI({ - url: 'https://helloacm.com/api/random/?n=8&x=4', - pollingInterval: 3000, - }); - - return ( - <> - ID: {data} - - - - - - - ); -}; diff --git a/packages/hooks/src/useAPI/demo/demo4.tsx b/packages/hooks/src/useAPI/demo/demo4.tsx deleted file mode 100644 index 3a258ffac2..0000000000 --- a/packages/hooks/src/useAPI/demo/demo4.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/** - * title: Modifying the request method - * desc: Using your custom request method. - * - * title.zh-CN: 修改 request 方法 - * desc.zh-CN: 使用自定义的 request 方法。 - */ - -import React from 'react'; -import { Button, notification } from 'antd'; -import { useAPI } from '@umijs/hooks'; - -export default () => { - const { run } = useAPI({ - url: 'https://helloacm.com/api/random/?n=8&x=4', - manual: true, - method: (...args) => { - notification.success({ - description: `request sent, url is ${args[0]}`, - message: 'fake request', - }); - return new Promise(resolve => resolve(null)); - }, - }); - - return ( - <> - - - - - ); -}; diff --git a/packages/hooks/src/useAPI/index.en-US.md b/packages/hooks/src/useAPI/index.en-US.md deleted file mode 100644 index 65e017adcb..0000000000 --- a/packages/hooks/src/useAPI/index.en-US.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: useAPI -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /deprecated/use-api ---- - -# useAPI - - -⚠️WARNING: useAPI is deprecated and will be removed in the next major version. Please use useRequest instead. - - -A custom hook that helps you sending and receiving data from server, using `umi-request` as default request library. -Supporting manual-trigged fetch and fetch in interval. -> This hook is meant to show a practice of wrapping useAsync. You may not need umi-request in your project. However, you can wrap your own useAPI accoding to [the way useAPI do it](https://github.com/umijs/hooks/blob/master/src/useAPI/index.ts). You can add request headers, transform data structures, or do some common error handling here. if our useAPI works in your project, you can also directly use it for sure. - -## Examples - -### Default usage - - - - -### Sending request manually - - - - -### Polling - - - - -### Modifying the request method - - - - -## API - -See [useAsync](./useAsync) diff --git a/packages/hooks/src/useAPI/index.ts b/packages/hooks/src/useAPI/index.ts deleted file mode 100644 index c081d8a4cf..0000000000 --- a/packages/hooks/src/useAPI/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import useAsync from '../useAsync'; - -interface IProps { - url: string; - options?: RequestInit; - manual?: boolean; - pollingInterval?: number; - method?: (url: string, options?: RequestInit) => Promise; - onSuccess?: (d: T) => void; - onError?: (e: Error) => void; -} - -let globalMethod: (url: string, options?: RequestInit) => Promise; - -export const configRequest = (method: () => any) => { - globalMethod = method; -}; - -const useAPI = (opt: IProps) => { - const requestMethod = opt.method || globalMethod || fetch; - return useAsync( - async () => { - const res = await requestMethod(opt.url, opt.options); - return res.json && typeof res.json === 'function' ? res.json() : res; - }, - [JSON.stringify(opt)], - { - manual: opt.manual, - pollingInterval: opt.pollingInterval, - onError: opt.onError, - onSuccess: opt.onSuccess, - }, - ); -}; - -export default useAPI; diff --git a/packages/hooks/src/useAPI/index.zh-CN.md b/packages/hooks/src/useAPI/index.zh-CN.md deleted file mode 100644 index d9730cbc1d..0000000000 --- a/packages/hooks/src/useAPI/index.zh-CN.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: useAPI -nav: - title: Hooks - path: /hooks -group: - title: 废弃 - path: /deprecated -legacy: /zh-CN/deprecated/use-api ---- - -# useAPI - - -⚠️警告: useAPI 已经被废弃了,将在下一个大版本时移除,你可以使用 useRequest 代替。 - - -一个内置 `umi-request`,帮你管理网络请求的 Hook。 -支持立即执行,手动触发执行,轮询。 -> 这个 Hook 主要展示了如何封装 useAsync 能力,可能您不需要使用 umi-request, -但是可以参照 [useAPI 的方式](https://github.com/umijs/hooks/blob/master/src/useAPI/index.ts)封装 useAsync。在这里可以添加请求头信息,根据接口格式做统一报错处理,数据转换等等。 -当然,如果 useAPI 可以满足您的需求,也可以直接在您的业务中使用。 - -## 代码演示 - -### 默认用法 - - - -### 手动触发执行 - - - -### 轮询 - - - -### 修改 request 方法 - - - -## API - -接口参考 [useAsync](./useAsync) diff --git a/packages/hooks/src/useAntdTable/__tests__/index.test.ts b/packages/hooks/src/useAntdTable/__tests__/index.test.ts deleted file mode 100644 index be7c6aa7f7..0000000000 --- a/packages/hooks/src/useAntdTable/__tests__/index.test.ts +++ /dev/null @@ -1,303 +0,0 @@ -import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks'; -import { DependencyList } from 'react'; -import useAntdTable, { Options, ReturnValue } from '../index'; - -interface Query { - current: number; - pageSize: number; - [key: string]: any; -} - -describe('useAntdTable', () => { - const originalError = console.error; - beforeAll(() => { - console.error = (...args: any) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return; - } - originalError.call(console, ...args); - }; - }); - afterAll(() => { - console.error = originalError; - }); - // jest.useFakeTimers(); - let queryArgs: any; - const asyncFn = (query: Query) => { - queryArgs = query; - return Promise.resolve({ - current: query.current, - total: 20, - pageSize: query.pageSize, - data: [], - }); - }; - - const form: any = { - initialValue: { - name: 'default name', - }, - fieldsValue: { - name: 'default name', - }, - getFieldsValue() { - return this.fieldsValue; - }, - getFieldInstance(key: string) { - return key in this.fieldsValue; - }, - setFieldsValue(values: object) { - this.fieldsValue = values; - }, - resetFields() { - this.fieldsValue = { ...this.initialValue }; - }, - }; - - const changeSearchType = (type: any) => { - if (type === 'simple') { - form.setFieldsValue({ - name: form.fieldsValue.name, - }); - } else { - form.setFieldsValue({ - name: form.fieldsValue.name, - email: form.fieldsValue.email, - phone: form.fieldsValue.phone, - }); - } - }; - - const setUp = ({ asyncFn: fn, deps, options }: any) => - renderHook(() => useAntdTable(fn, deps, options)); - - let hook: RenderHookResult< - { func: (...args: any[]) => Promise<{}>; deps: DependencyList; opt: Options }, - ReturnValue - >; - - it('should be defined', () => { - expect(useAntdTable).toBeDefined(); - }); - - it('should fetch after first render', async () => { - queryArgs = undefined; - act(() => { - hook = setUp({ - asyncFn, - }); - }); - - expect(hook.result.current.tableProps.loading).toEqual(true); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(10); - await hook.waitForNextUpdate(); - expect(hook.result.current.tableProps.loading).toEqual(false); - expect(hook.result.current.tableProps.pagination.current).toEqual(1); - expect(hook.result.current.tableProps.pagination.pageSize).toEqual(10); - expect(hook.result.current.tableProps.pagination.total).toEqual(20); - }); - it('should sorter, filters work', async () => { - queryArgs = undefined; - act(() => { - hook = setUp({ - asyncFn, - }); - }); - await hook.waitForNextUpdate(); - act(() => { - hook.result.current.tableProps.onChange({ - current: 2, - pageSize: 5, - }); - }); - await hook.waitForNextUpdate(); - expect(hook.result.current.tableProps.pagination.current).toEqual(2); - /* 改变 filter, sorter */ - act(() => { - hook.result.current.tableProps.onChange( - { - current: 2, - pageSize: 5, - }, - { gender: ['male'] }, - { field: 'email', order: 'ascend' } as any, - ); - }); - await hook.waitForNextUpdate(); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(5); - expect(queryArgs.sorter.field).toEqual('email'); - expect(queryArgs.sorter.order).toEqual('ascend'); - expect(queryArgs.filters.gender[0]).toEqual('male'); - }); - it('should form, defaultPageSize, id work', async () => { - queryArgs = undefined; - act(() => { - hook = setUp({ - asyncFn, - deps: [], - options: { form, defaultPageSize: 5, id: 'tableId' }, - }); - }); - await hook.waitForNextUpdate(); - const { search } = hook.result.current; - expect(hook.result.current.tableProps.loading).toEqual(false); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(5); - expect(queryArgs.name).toEqual('default name'); - expect(search).toBeDefined(); - if (search) { - expect(search.type).toEqual('simple'); - } - - // /* 切换 分页 */ - act(() => { - hook.result.current.tableProps.onChange({ - current: 2, - pageSize: 5, - }); - }); - await hook.waitForNextUpdate(); - expect(queryArgs.current).toEqual(2); - expect(queryArgs.pageSize).toEqual(5); - expect(queryArgs.name).toEqual('default name'); - - /* 改变 name, 提交表单 */ - form.fieldsValue.name = 'change name'; - act(() => { - if (search) { - search.submit(); - } - }); - await hook.waitForNextUpdate(); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(5); - expect(queryArgs.name).toEqual('change name'); - - // /* 切换 searchType 到 advance */ - act(() => { - if (search) { - search.changeType(); - changeSearchType('advance'); - } - }); - if (hook.result.current.search) { - expect(hook.result.current.search.type).toEqual('advance'); - } - act(() => { - if (hook.result.current.search) { - hook.result.current.search.submit(); - } - }); - await hook.waitForNextUpdate(); - - expect(queryArgs.current).toEqual(1); - expect(queryArgs.name).toEqual('change name'); - - // /* 手动改变其他两个字段的值 */ - form.fieldsValue.phone = '13344556677'; - form.fieldsValue.email = 'x@qq.com'; - - act(() => { - if (hook.result.current.search) { - hook.result.current.search.submit(); - } - }); - await hook.waitForNextUpdate(); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.name).toEqual('change name'); - expect(queryArgs.phone).toEqual('13344556677'); - expect(queryArgs.email).toEqual('x@qq.com'); - - // /* 改变 name,但是不提交,切换到 simple 去 */ - form.fieldsValue.name = 'change name 2'; - act(() => { - if (hook.result.current.search) { - hook.result.current.search.changeType(); - changeSearchType('simple'); - } - }); - - if (hook.result.current.search) { - expect(hook.result.current.search.type).toEqual('simple'); - } - expect(form.fieldsValue.name).toEqual('change name 2'); - - // /* 提交 */ - act(() => { - if (hook.result.current.search) { - hook.result.current.search.submit(); - } - }); - await hook.waitForNextUpdate(); - - expect(queryArgs.name).toEqual('change name 2'); - expect(queryArgs.phone).toBeUndefined(); - expect(queryArgs.email).toBeUndefined(); - - // /* 切换回 advance,恢复之前的条件 */ - act(() => { - if (hook.result.current.search) { - hook.result.current.search.changeType(); - } - changeSearchType('advance'); - }); - - if (hook.result.current.search) { - expect(hook.result.current.search.type).toEqual('advance'); - } - expect(form.fieldsValue.name).toEqual('change name 2'); - expect(form.fieldsValue.phone).toEqual('13344556677'); - expect(form.fieldsValue.email).toEqual('x@qq.com'); - - act(() => { - hook.result.current.tableProps.onChange({ - current: 3, - pageSize: 5, - }); - }); - await hook.waitForNextUpdate(); - // /* 卸载重装 */ - form.fieldsValue = { - name: '', - phone: '', - email: '', - }; - act(() => { - hook.unmount(); - }); - act(() => { - hook = setUp({ - asyncFn, - deps: [], - options: { form, defaultPageSize: 5, id: 'tableId' }, - }); - }); - - if (hook.result.current.search) { - expect(hook.result.current.search.type).toEqual('advance'); - } - expect(hook.result.current.tableProps.pagination.current).toEqual(3); - expect(form.fieldsValue.name).toEqual('change name 2'); - expect(form.fieldsValue.phone).toEqual('13344556677'); - expect(form.fieldsValue.email).toEqual('x@qq.com'); - - /* refresh */ - act(() => { - hook.result.current.refresh(); - }); - expect(hook.result.current.tableProps.loading).toEqual(true); - await hook.waitForNextUpdate(); - /* reset */ - act(() => { - if (hook.result.current.search) { - hook.result.current.search.reset(); - } - }); - - expect(form.fieldsValue.name).toEqual('default name'); - expect(form.fieldsValue.phone).toBeUndefined(); - expect(form.fieldsValue.email).toBeUndefined(); - }); -}); diff --git a/packages/hooks/src/useAntdTable/demo/demo1.tsx b/packages/hooks/src/useAntdTable/demo/demo1.tsx deleted file mode 100644 index 1b47d7503e..0000000000 --- a/packages/hooks/src/useAntdTable/demo/demo1.tsx +++ /dev/null @@ -1,59 +0,0 @@ -/** - * title: Default usage - * desc: Automatically handle paged data. - * - * title.zh-CN: 基本用法 - * desc.zh-CN: 自动处理分页数据 - */ - -import { Table } from 'antd'; -import React from 'react'; -import { useAntdTable } from '@umijs/hooks' -import { FnParams } from '@umijs/hooks/es/useAntdTable'; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -const getTableData = ({ current, pageSize }: FnParams) => - fetch(`https://randomuser.me/api?results=55&page=${current}&size=${pageSize}`) - .then(res => res.json()) - .then(res => ({ - total: res.info.results, - data: res.results, - })); - -export default () => { - const { tableProps } = useAntdTable(getTableData); - - const columns = [ - { - title: 'name', - dataIndex: 'name.last', - }, - { - title: 'email', - dataIndex: 'email', - }, - { - title: 'phone', - dataIndex: 'phone', - }, - { - title: 'gender', - dataIndex: 'gender', - }, - ]; - - return ; -}; diff --git a/packages/hooks/src/useAntdTable/demo/demo2.tsx b/packages/hooks/src/useAntdTable/demo/demo2.tsx deleted file mode 100644 index 225cd45460..0000000000 --- a/packages/hooks/src/useAntdTable/demo/demo2.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/** - * title: Filter And Sorter - * desc: Retrieve filter and sorter from antd table. Page number will be reset when filter or sorter changes. - * - * title.zh-CN: 排序与筛选 - * desc.zh-CN: 自动处理 Table 的排序与筛选,在修改排序或筛选时,会初始化到第一页 - */ - -import { Table } from 'antd'; -import React from 'react'; -import { useAntdTable } from '@umijs/hooks' -import { FnParams } from '@umijs/hooks/es/useAntdTable'; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -const getTableData = ({ current, pageSize, sorter, filters }: FnParams) => { - console.log(current, pageSize, sorter, filters); - let url = `https://randomuser.me/api?results=55&page=${current}&size=${pageSize}`; - if (sorter && sorter.field && sorter.order) { - url += `&${sorter.field}=${sorter.order}`; - } - if (filters) { - Object.entries(filters).forEach(i => { - url += `&${i[0]}=${i[1]}`; - }); - } - return fetch(url) - .then(res => res.json()) - .then(res => ({ - total: res.info.results, - data: res.results, - })); -}; - -export default () => { - const { tableProps, filters, sorter } = useAntdTable(getTableData, { - defaultPageSize: 5, - }); - - const columns = [ - { - title: 'name', - dataIndex: 'name.last', - }, - { - title: 'email', - dataIndex: 'email', - }, - { - title: 'phone', - dataIndex: 'phone', - sorter: true, - sortOrder: sorter.field === 'phone' && sorter.order, - }, - { - title: 'gender', - dataIndex: 'gender', - filters: [{ text: 'male', value: 'male' }, { text: 'female', value: 'female' }], - filteredValue: filters.gender, - }, - ]; - - return
; -}; diff --git a/packages/hooks/src/useAntdTable/demo/demo3.tsx b/packages/hooks/src/useAntdTable/demo/demo3.tsx deleted file mode 100644 index 7dd6cb86e2..0000000000 --- a/packages/hooks/src/useAntdTable/demo/demo3.tsx +++ /dev/null @@ -1,96 +0,0 @@ -/** - * title: Table with filter and page size switcher - * desc: use deps properly, when deps changes, page number will be reset. - * - * title.zh-CN: 带筛选和分页器的 Table - * desc.zh-CN: 合理利用 deps,当 deps 变化时,会初始化到第一页 - */ - -import { Select, Table } from 'antd'; -import React, { useState } from 'react'; -import { useAntdTable } from '@umijs/hooks' -import { FnParams } from '@umijs/hooks/es/useAntdTable'; - -const { Option } = Select; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -type Gender = 'male' | 'female'; - -const getTableData = ({ current, pageSize, gender }: FnParams) => - fetch(`https://randomuser.me/api?results=55&page=${current}&size=${pageSize}&gender=${gender}`) - .then(res => res.json()) - .then(res => ({ - total: res.info.results, - data: res.results, - })); - -export default () => { - const [gender, setGender] = useState('male'); - const { tableProps } = useAntdTable( - params => - getTableData({ - ...params, - gender, - }), - [gender], - { - defaultPageSize: 5, - }, - ); - - const columns = [ - { - title: 'name', - dataIndex: 'name.last', - }, - { - title: 'email', - dataIndex: 'email', - }, - { - title: 'phone', - dataIndex: 'phone', - }, - { - title: 'gender', - dataIndex: 'gender', - }, - ]; - - return ( - <> - -
- - ); -}; diff --git a/packages/hooks/src/useAntdTable/demo/demo4.tsx b/packages/hooks/src/useAntdTable/demo/demo4.tsx deleted file mode 100644 index 68fdfeb6d9..0000000000 --- a/packages/hooks/src/useAntdTable/demo/demo4.tsx +++ /dev/null @@ -1,140 +0,0 @@ -/** - * title: Search form and table data binding - * desc: If options have the form parameter, useAntdTable will take care of form data changing and data caching. - * - * title.zh-CN: 搜索表单与列表联动 - * desc.zh-CN: 如果 options 传了 form 参数,则我们会帮你管理 form 数据 - */ - -import React from 'react'; -import { Button, Col, Form, Input, Row, Table, Select } from 'antd'; -import { WrappedFormUtils } from 'antd/lib/form/Form'; -import { useAntdTable } from '@umijs/hooks' -import { FnParams } from '@umijs/hooks/es/useAntdTable'; - -const { Option } = Select; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -interface AppListProps { - form: WrappedFormUtils; -} - -const getTableData = ({ current, pageSize, ...rest }: FnParams) => { - console.log(current, pageSize, rest); - return fetch(`https://randomuser.me/api?results=55&page=${current}&size=${pageSize}`) - .then(res => res.json()) - .then(res => ({ - total: res.info.results, - data: res.results, - })); -}; - -const AppList = (props: AppListProps) => { - const { getFieldDecorator } = props.form; - const { tableProps, search } = useAntdTable(getTableData, { - defaultPageSize: 5, - form: props.form, - }); - - const { type, changeType, submit, reset } = search || {}; - - const columns = [ - { - title: 'name', - dataIndex: 'name.last', - }, - { - title: 'email', - dataIndex: 'email', - }, - { - title: 'phone', - dataIndex: 'phone', - }, - { - title: 'gender', - dataIndex: 'gender', - }, - ]; - - const advanceSearchForm = ( -
-
- -
- - {getFieldDecorator('name')()} - - - - - {getFieldDecorator('email')()} - - - - - {getFieldDecorator('phone')()} - - - - - - - - - - - - - ); - - const searchFrom = ( -
-
- {getFieldDecorator('gender', { - initialValue: '', - })( - , - )} - {getFieldDecorator('name')( - , - )} - - -
- ); - - return ( -
- {type === 'simple' ? searchFrom : advanceSearchForm} -
- - ); -}; - -export default Form.create()(AppList); diff --git a/packages/hooks/src/useAntdTable/demo/demo5.tsx b/packages/hooks/src/useAntdTable/demo/demo5.tsx deleted file mode 100644 index bc902f1f32..0000000000 --- a/packages/hooks/src/useAntdTable/demo/demo5.tsx +++ /dev/null @@ -1,135 +0,0 @@ -/** - * title: Data caching - * desc: If id shows in the options, All the data related to the table will be cached in memory. - * - * title.zh-CN: 数据缓存 - * desc.zh-CN: 如果 options 传了 id 参数,则我们会将当前表单数据、分页数据、筛选排序等数据全部缓存下来,下次构建时恢复缓存数据 - */ - -import { Button, Form, Input, Table } from 'antd'; -import React, { useState } from 'react'; -import { WrappedFormUtils } from 'antd/lib/form/Form'; -import { useAntdTable } from '@umijs/hooks' -import { FnParams } from '@umijs/hooks/es/useAntdTable'; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -interface AppListProps { - form: WrappedFormUtils; -} - -const getTableData = ({ current, pageSize, ...rest }: FnParams) => { - console.log(current, pageSize, rest); - return fetch(`https://randomuser.me/api?results=55&page=${current}&size=${pageSize}`) - .then(res => res.json()) - .then(res => ({ - total: res.info.results, - data: res.results, - })); -}; - -const AppList = (props: AppListProps) => { - const { getFieldDecorator } = props.form; - const { tableProps, filters, sorter, search } = useAntdTable(getTableData, { - defaultPageSize: 5, - form: props.form, - id: 'tableId', - }); - - const { type, changeType, submit, reset } = search || {}; - - const columns = [ - { - title: 'name', - dataIndex: 'name.last', - }, - { - title: 'email', - dataIndex: 'email', - }, - { - title: 'phone', - dataIndex: 'phone', - sorter: true, - sortOrder: sorter.field === 'phone' && sorter.order, - }, - { - title: 'gender', - dataIndex: 'gender', - filters: [{ text: 'male', value: 'male' }, { text: 'female', value: 'female' }], - filteredValue: filters.gender, - }, - ]; - - const searchFrom = ( -
-
- {getFieldDecorator('name')( - , - )} - - {type === 'advance' && ( - <> - {getFieldDecorator('email')( - , - )} - {getFieldDecorator('phone')( - , - )} - - )} - - - - -
- ); - - return ( -
- {searchFrom} -
- - ); -}; - -const AppListTable = Form.create()(AppList); - -const Demo = () => { - const [show, setShow] = useState(true); - - return ( -
- - {show && } -
- ); -}; - -export default Demo; diff --git a/packages/hooks/src/useAntdTable/index.en-US.md b/packages/hooks/src/useAntdTable/index.en-US.md deleted file mode 100644 index e0c666ae80..0000000000 --- a/packages/hooks/src/useAntdTable/index.en-US.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: useAntdTable -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /deprecated/use-antd-table ---- - -# useAntdTable - - -

⚠️WARNING: useAntdTable is deprecated and will be removed in the next major version.

-

Simple AntD Table(demo1, demo2, demo3),you can use useRequest pagination mode instead.

-

Complex AntD Table with Form(demo4, demo5),you can use useFormTable instead.

-
- -Encapsulates common logic to make it easier to manage [Antd Table](https://ant.design/components/table/)。 - -**Core Characteristics** - -* Automatically handle table pagination -* Connected search form and table data -* Support simple and complex mode switching, different search types are cached separately -* Support data caching, automatically restore table data and search form when navigate away and then go back. - -## Examples - -### Default usage - - - -### Filter And Sorter - - - -### Table with filter and pager - - - -### Search form and table data binding - - - -### Data cache - - - -## API - -```javascript -const result: ReturnValue = useAntdTable( - asyncFn: (params: any) => Promise, - options?: Options, -); - -const result: ReturnValue = useAntdTable( - asyncFn: (params: any) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -``` -interface ReturnValue { - tableProps: { - dataSource: Item[]; - loading: boolean; - onChange: ( - pagination: PaginationConfig, - filters?: Record, - sorter?: SorterResult, - ) => void; - pagination: { - current: number; - pageSize: number; - total: number; - }; - }; - sorter: SorterResult; - filters: Record; - refresh: () => void; - search?: { - type: 'simple' | 'advance'; - changeType: () => void; - submit: () => void; - reset: () => void; - }; -} - -``` -| Property | Description | Type | Default | -|--------------------------------|-----------------------------------------------|---------------------------------------|--------------------| -| tableProps.loading | Whether it is loading | boolean | false | -| tableProps.dataSource | Table data to use | array | - | -| tableProps.onChange | OnChange function of the antd Table component | (pagination, filters, sorter) => void | - | -| tableProps.pagination.current | Current page number | number | 1 | -| tableProps.pagination.pageSize | Amount of data per page | number | 10 | -| tableProps.pagination.total | Total amount of data | number | 0 | -| sorter | Sort data | antd sorter | {} | -| filters | Filter data | antd filters | {} | -| refresh | Refresh current data | () => void | - | -| search.type | Search type | 'simple'\|'advance' |'simple' | -| search.changeType | Trigger search type switch | () => void | - | -| search.submit | Trigger search | () => void | - | -| search.reset | Reset search | () => void | - | - -### Params - -| Property | Description | Type | Default | -|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|---------| -| asyncFn | The function requesting data, the function parameters are current, pageSize, sorter, filters, and the current search form data. The return data structure expectation is `{current?: number, pageSize?: number, total: number, data: Item[]}` . Of course, you can return the result by options.formatResult, post formatting. | (params)=> Promise | - | -| deps | Depends on the array, if the deps changes, it will trigger asyncFn | any[] | [] | -| options | Optional configuration item, see Options | - | - | - -### Options - -| Property | Description | Type | Default | -|-----------------|-----------------------------------------------------------------------------------------------------------------------|--------|---------| -| defaultPageSize | Default amount of data per page | number | 10 | -| id | The table unique id, and if there is an id, it will automatically cache and recover the data. | string | - | -| form | Antd form instance, if there is a form instance, there will be a search object in the asyncFn params | - | - | -| formatResult | Format the asyncFn return data. If the asyncFn return data meets the requirements, then this parameter is not needed. | - | - | - - -## Remarks - -In production, the pagination configuration and the API data structure are usually identical in each project. If we config pagination and formatResult each time we use `useAntdTable`, it is definitely not elegant, so we recommend that you should repackaged a new hook based on `useAntdTable` in your project, for example: - -```javascript -import { useAntdTable } from '@umijs/hooks' - -export default (fn, deps = [], options = {}) => { - const result = useAntdTable(fn, deps, { - formatResult: res => ({ - total: res.data.pagination.total, - data: res.data.list, - }), - ...options, - }) - result.tableProps.pagination.showQuickJumper = true - result.tableProps.pagination.showSizeChanger = true - result.tableProps.pagination.hideOnSinglePage = true - result.tableProps.pagination.showTotal = total => `共 ${total} 条` - return result -} -``` diff --git a/packages/hooks/src/useAntdTable/index.ts b/packages/hooks/src/useAntdTable/index.ts deleted file mode 100644 index 09e881d034..0000000000 --- a/packages/hooks/src/useAntdTable/index.ts +++ /dev/null @@ -1,421 +0,0 @@ -import { - DependencyList, - useCallback, - useEffect, - useReducer, - useRef, - useMemo, - Reducer, -} from 'react'; -import isEqual from 'lodash.isequal'; -import { PaginationConfig, Sorter, Filter } from './typings'; -import useAsync from '../useAsync'; -import useUpdateEffect from '../useUpdateEffect'; - -interface UseAntdTableFormUtils { - getFieldInstance?: (name: string) => {}; - setFieldsValue?: (value: { [key: string]: any }) => void; - getFieldsValue?: (...args: any) => any; - resetFields?: () => void; - [key: string]: any; -} - -export interface ReturnValue { - /* table 已经废弃 */ - table?: { - dataSource: Item[]; - loading: boolean; - onChange: (pagination: PaginationConfig, filters?: Filter, sorter?: Sorter) => void; - pagination: { - current: number; - pageSize: number; - total: number; - } & { [K in keyof PaginationConfig]?: PaginationConfig[K] }; - }; - tableProps: { - dataSource: Item[]; - loading: boolean; - onChange: (pagination: PaginationConfig, filters?: Filter, sorter?: Sorter) => void; - pagination: { - current: number; - pageSize: number; - total: number; - } & { [K in keyof PaginationConfig]?: PaginationConfig[K] }; - }; - sorter: Sorter; - filters: Filter; - refresh: () => void; - // TODO 如果有 form,则一定有 search - search?: { - type: 'simple' | 'advance'; - changeType: () => void; - submit: () => void; - reset: () => void; - }; -} - -export interface Options { - defaultPageSize?: number; - id?: string; - form?: UseAntdTableFormUtils; - formatResult?: ( - result: Result | undefined, - ) => { - current?: number; - pageSize?: number; - total: number; - data: Item[]; - }; -} - -// Item 如何变成可选的? -export interface FnParams { - current: number; - pageSize: number; - sorter?: Sorter; - filters?: Filter; - [key: string]: any; -} - -interface FormData { - [key: string]: any; -} - -class UseTableInitState { - // 搜索类型,简单、高级 - searchType: 'simple' | 'advance' = 'simple'; - - // 当前页码 - current = 1; - - // 分页大小 - pageSize = 10; - - // 总页数 - total = 0; - - // 全量表单数据 - formData: FormData = {}; - - // active 表单数据 - activeFormData: FormData = {}; - - // 计数器 - count = 0; - - // 列表数据 - data: Item[] = []; - - filters: Filter = {} as Filter; - - sorter: Sorter = {} as Sorter; -} - -// 缓存 -const cacheData: { [key: string]: any } = {}; - -const reducer = (state: UseTableInitState, action: { type: string; payload?: {} }) => { - switch (action.type) { - case 'updateState': - return { ...state, ...action.payload }; - default: - throw new Error(); - } -}; - -function useAntdTable( - fn: (params: FnParams) => Promise, - options?: Options, -): ReturnValue; -function useAntdTable( - fn: (params: FnParams) => Promise, - deps?: DependencyList, - options?: Options, -): ReturnValue; -function useAntdTable( - fn: (params: FnParams) => Promise, - deps?: DependencyList | Options, - options?: Options, -): ReturnValue { - const _deps: DependencyList = (Array.isArray(deps) ? deps : []) as DependencyList; - const _options: Options = (typeof deps === 'object' && !Array.isArray(deps) - ? deps - : options || {}) as Options; - - const initState = useMemo(() => new UseTableInitState(), []); - - const { defaultPageSize = 10, id, form, formatResult } = _options; - const [state, dispatch] = useReducer, any>>(reducer, { - ...initState, - pageSize: defaultPageSize, - }); - - /* 临时记录切换前的表单数据 */ - const tempFieldsValueRef = useRef({}); - - const stateRef = useRef({} as UseTableInitState); - stateRef.current = state; - const { run, loading } = useAsync(fn, _deps, { - manual: true, - }); - - const reload = useCallback(() => { - dispatch({ - type: 'updateState', - payload: { - current: 1, - count: state.count + 1, - }, - }); - }, [state.count]); - - const refresh = useCallback(() => { - dispatch({ - type: 'updateState', - payload: { count: state.count + 1 }, - }); - }, [state.count]); - - /* 初始化执行 */ - useEffect(() => { - /* 有缓存,恢复 */ - if (id && cacheData[id]) { - const cache = cacheData[id]; - /* 修改完 formData 和 searchType 之后,会触发 useUpdateEffect,给当前表单赋值 */ - dispatch({ - type: 'updateState', - payload: { - current: cache.current, - pageSize: cache.pageSize, - searchType: cache.searchType, - activeFormData: cache.activeFormData, - formData: cache.formData, - filters: cache.filters, - sorter: cache.sorter, - count: state.count + 1, - }, - }); - } else if (form) { - /* 如果有 form,需要走 searchSubmit,为了初始化的时候,拿到 initialValue */ - searchSubmit(); - } else { - refresh(); - } - - if (id) { - return () => { - cacheData[id] = stateRef.current; - }; - } - return () => {}; - }, []); - - /* deps 变化后,重置表格 */ - useUpdateEffect(() => { - reload(); - }, _deps); - - /* state.count 变化时,重新请求数据 */ - useUpdateEffect(() => { - const formattedData: FormData = {}; - /* 把 undefined 的过滤掉 */ - Object.keys(state.activeFormData).forEach(key => { - if (state.activeFormData[key] !== undefined) { - formattedData[key] = state.activeFormData[key]; - } - }); - - const params: any = { - current: state.current, - pageSize: state.pageSize, - ...formattedData, - }; - if (state.filters) { - params.filters = state.filters; - } - if (state.sorter) { - params.sorter = state.sorter; - } - run(params).then(res => { - const payload = formatResult ? formatResult(res) : res; - dispatch({ - type: 'updateState', - payload, - }); - }); - }, [state.current, state.pageSize, state.count]); - - /* 改变了 searchType,或者 formData,恢复表单数据 */ - useUpdateEffect(() => { - if (!form) { - return; - } - const targetFormData = { ...state.formData, ...tempFieldsValueRef.current }; - const existFormData: FormData = {}; - Object.keys(targetFormData).forEach((key: string) => { - if (form.getFieldInstance ? form.getFieldInstance(key) : true) { - existFormData[key] = targetFormData[key]; - } - }); - if (form.setFieldsValue) { - form.setFieldsValue(existFormData); - } - tempFieldsValueRef.current = {}; - }, [state.searchType, state.formData]); - - /* 获得当前 form 数据 */ - const getCurrentFieldsValues = useCallback(() => { - if (!form) { - return []; - } - let fieldsValue = {} as FormData; - if (form.getFieldsValue) { - fieldsValue = form.getFieldsValue(); - } - const filterFiledsValue: FormData = {}; - Object.keys(fieldsValue).forEach((key: string) => { - if (form.getFieldInstance ? form.getFieldInstance(key) : true) { - filterFiledsValue[key] = fieldsValue[key]; - } - }); - return filterFiledsValue; - }, [form]); - - // 表单搜索 - const searchSubmit = useCallback( - (e?: string | React.MouseEvent | React.KeyboardEvent) => { - if (!form) { - return; - } - if (e && (e as React.MouseEvent).preventDefault) { - (e as React.MouseEvent).preventDefault(); - } - - setTimeout(() => { - const activeFormData = getCurrentFieldsValues(); - dispatch({ - type: 'updateState', - payload: { - activeFormData, - formData: { ...state.formData, ...activeFormData }, - }, - }); - reload(); - }); - }, - [form, reload], - ); - - // 重置表单 - const searchReset = useCallback(() => { - if (!form) { - return; - } - // 恢复初始值 - if (form.resetFields) { - form.resetFields(); - } - // 重置表单后,拿到当前默认值 - const activeFormData = getCurrentFieldsValues(); - - dispatch({ - type: 'updateState', - payload: { - activeFormData, - formData: activeFormData, - }, - }); - - reload(); - }, [form, reload]); - - // 切换搜索类型 - const changeSearchType = useCallback(() => { - if (!form) { - return; - } - tempFieldsValueRef.current = getCurrentFieldsValues(); - const targetSearchType = state.searchType === 'simple' ? 'advance' : 'simple'; - dispatch({ - type: 'updateState', - payload: { - searchType: targetSearchType, - }, - }); - }, [state.searchType]); - - // 表格翻页 排序 筛选等 - const changeTable = useCallback( - (p: PaginationConfig, f: Filter = {} as Filter, s: Sorter = {} as Sorter) => { - // antd table 的初始状态 filter 带有 null 字段,需要先去除后再比较 - const realFilter = { ...f }; - Object.entries(realFilter).forEach(item => { - if (item[1] === null) { - delete (realFilter as Object)[item[0] as keyof Object]; - } - }); - - // fix: https://github.com/umijs/hooks/issues/338 - if (!s.order) { - // eslint-disable-next-line no-param-reassign - s.field = undefined; - } - - const needReload = - !isEqual(realFilter, state.filters) || - s.field !== state.sorter.field || - s.order !== state.sorter.order; - - dispatch({ - type: 'updateState', - payload: { - current: needReload ? 1 : p.current, - pageSize: p.pageSize, - count: state.count + 1, - filters: f, - sorter: s, - }, - }); - }, - [state.count], - ); - - const result: ReturnValue = { - /* table 已经废弃 */ - table: { - dataSource: state.data, - loading, - onChange: changeTable, - pagination: { - current: state.current, - pageSize: state.pageSize, - total: state.total, - }, - }, - tableProps: { - dataSource: state.data, - loading, - onChange: changeTable, - pagination: { - current: state.current, - pageSize: state.pageSize, - total: state.total, - }, - }, - sorter: state.sorter, - filters: state.filters, - refresh, - }; - if (form) { - result.search = { - submit: searchSubmit, - type: state.searchType, - changeType: changeSearchType, - reset: searchReset, - }; - } - - return result; -} - -export default useAntdTable; diff --git a/packages/hooks/src/useAntdTable/index.zh-CN.md b/packages/hooks/src/useAntdTable/index.zh-CN.md deleted file mode 100644 index 702a0595d8..0000000000 --- a/packages/hooks/src/useAntdTable/index.zh-CN.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: useAntdTable -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /zh-CN/deprecated/use-antd-table ---- - - -# useAntdTable - - -

⚠️警告: useAntdTable 已经被废弃了,将在下一个大版本时移除。

-

一般的 AntD Table(demo1, demo2, demo3),你可以使用 useRequest 分页模式代替。

-

复杂的与 Form 联动的 Table(demo4, demo5),你可以使用 useFormTable 代替。

-
- -封装了常用的逻辑,让你更轻松的管理 [Antd Table](https://ant.design/components/table/)。 - -**核心特性** - -* 表格分页处理 -* 搜索表单与表格联动 -* 支持简单、复杂 2 种搜索模式切换,并且在切换模式时,能自动填充上一次的数据 -* 支持数据缓存,组件销毁重建时能自动还原上一次的表单数据,分页状态等 - -## 代码演示 - -### 基本用法 - - - -### 排序与筛选 - - - -### 带筛选和分页器的 Table - - - -### 搜索表单与列表联动 - - - -### 数据缓存 - - - -## API - -```javascript -const result: ReturnValue = useAntdTable( - asyncFn: (params: any) => Promise, - options?: Options, -); - -const result: ReturnValue = useAntdTable( - asyncFn: (params: any) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -``` -interface ReturnValue { - tableProps: { - dataSource: Item[]; - loading: boolean; - onChange: ( - pagination: PaginationConfig, - filters?: Record, - sorter?: SorterResult, - ) => void; - pagination: { - current: number; - pageSize: number; - total: number; - }; - }; - sorter: SorterResult; - filters: Record; - refresh: () => void; - search?: { - type: 'simple' | 'advance'; - changeType: () => void; - submit: () => void; - reset: () => void; - }; -} - -``` -| 参数 | 说明 | 类型 | 默认值 | -|--------------------------------|---------------------------------|---------------------------------------|--------------------| -| tableProps.loading | 是否正在加载 | boolean | false | -| tableProps.dataSource | table 需要使用的数据 | array | - | -| tableProps.onChange | antd Table 组件的 onChange 函数 | (pagination, filters, sorter) => void | - | -| tableProps.pagination.current | 当前页数 | number | 1 | -| tableProps.pagination.pageSize | 每页数据量 | number | 10 | -| tableProps.pagination.total | 数据总量 | number | 0 | -| sorter | 排序数据 | antd sorter | {} | -| filters | 筛选数据 | antd filters | {} | -| refresh | 刷新当前数据 | () => void | - | -| search.type | 搜索类型 | 'simple'\|'advance' |'simple' | -| search.changeType | 触发搜索类型切换 | () => void | - | -| search.submit | 触发搜索 | () => void | - | -| search.reset | 重置搜索 | () => void | - | - -### 参数 - -| 参数 | 说明 | 类型 | 默认值 | -|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|--------| -| asyncFn | 请求数据的函数,函数参数为 current, pageSize, sorter, filters,及当前搜索表单数据,返回数据结构期望为 `{current?: number, pageSize?: number, total: number, data: Item[]}`。当然你可以通过 options.formatResult,后置格式化返回结果 | (params)=> Promise | - | -| deps | 依赖数组,如果 deps 变化,会触发 asyncFn | any[] | [] | -| options | 可选配置项,见 Options s | - | - | - -### Options - -| 参数 | 说明 | 类型 | 默认值 | -|-----------------|------------------------------------------------------------------------------|--------|--------| -| defaultPageSize | 默认的每页数据量 | number | 10 | -| id | 表格唯一 id,如果有 id,则会自动缓存并恢复数据 | string | - | -| form | antd form 实例,如果有 form 实例,则 asyncFn 会收到 form 数据 | - | - | -| formatResult | 对 asyncFn 返回数据进行格式化,如果 asyncFn 返回数据符合要求,则不需要该参数 | - | - | - - -## 备注 - -在日常工作中,我们每个网站的 Pagination 配置,接口返回数据结构都是一致的,如果我们在每次使用 `useAntdTable` 时都单独处理 Pagination 和 formatResult 肯定是不优雅的,所以我们建议您在自己的项目中基于 `useAntdTable` 再封装一次,例如下面的示例: - -```javascript -import { useAntdTable } from '@umijs/hooks' - -export default (fn, deps = [], options = {}) => { - const result = useAntdTable(fn, deps, { - formatResult: res => ({ - total: res.data.pagination.total, - data: res.data.list, - }), - ...options, - }) - result.tableProps.pagination.showQuickJumper = true - result.tableProps.pagination.showSizeChanger = true - result.tableProps.pagination.hideOnSinglePage = true - result.tableProps.pagination.showTotal = total => `共 ${total} 条` - return result -} -``` diff --git a/packages/hooks/src/useAntdTable/typings.ts b/packages/hooks/src/useAntdTable/typings.ts deleted file mode 100644 index 9a8b0ecb3a..0000000000 --- a/packages/hooks/src/useAntdTable/typings.ts +++ /dev/null @@ -1,45 +0,0 @@ -export interface PaginationConfig { - total?: number; - defaultCurrent?: number; - disabled?: boolean; - current?: number; - defaultPageSize?: number; - pageSize?: number; - onChange?: (page: number, pageSize?: number) => void; - hideOnSinglePage?: boolean; - showSizeChanger?: boolean; - pageSizeOptions?: string[]; - onShowSizeChange?: (current: number, size: number) => void; - showQuickJumper?: - | boolean - | { - goButton?: React.ReactNode; - }; - showTotal?: (total: number, range: [number, number]) => React.ReactNode; - size?: string; - simple?: boolean; - style?: React.CSSProperties; - locale?: Object; - className?: string; - prefixCls?: string; - selectPrefixCls?: string; - itemRender?: ( - page: number, - type: 'page' | 'prev' | 'next' | 'jump-prev' | 'jump-next', - originalElement: React.ReactElement, - ) => React.ReactNode; - role?: string; - showLessItems?: boolean; - position?: 'top' | 'bottom' | 'both'; - [key: string]: any; -} - -export interface Sorter { - column?: any; - order?: 'ascend' | 'descend'; - field?: string; - columnKey?: string; - [key: string]: any; -} - -export type Filter = any; diff --git a/packages/hooks/src/useAsync/__tests__/index.test.ts b/packages/hooks/src/useAsync/__tests__/index.test.ts deleted file mode 100644 index 66638499c2..0000000000 --- a/packages/hooks/src/useAsync/__tests__/index.test.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { renderHook, act, RenderHookResult } from '@testing-library/react-hooks'; -import { DependencyList } from 'react'; -import useAsync, { ReturnValue, Options } from '../index'; - -describe('useAsync', () => { - const originalError = console.error; - beforeAll(() => { - jest.useFakeTimers(); - console.error = (...args: any) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return; - } - originalError.call(console, ...args); - }; - }); - afterAll(() => { - console.error = originalError; - }); - - const request = (req?: number) => - new Promise((resolve, reject) => { - setTimeout(() => { - if (req === 0) { - reject(new Error('fail')); - } else { - resolve('success'); - } - }, 2000); - }); - - it('should be defined', () => { - expect(useAsync).toBeDefined(); - }); - - let hook: RenderHookResult< - { func: (...args: any[]) => Promise<{}>; deps: DependencyList; opt: Options<{}> }, - ReturnValue<{}> - >; - - it('hooks should auto run', async () => { - const successCallback = jest.fn(); - const errorCallback = jest.fn(); - act(() => { - hook = renderHook( - ({ func }) => - useAsync(func, [], { - onSuccess: successCallback, - onError: errorCallback, - }), - { - initialProps: { - func: (req: number) => request(req), - }, - }, - ); - }); - - expect(hook.result.current.loading).toEqual(true); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.loading).toEqual(false); - expect(hook.result.current.data).toEqual('success'); - expect(errorCallback).not.toHaveBeenCalled(); - expect(successCallback).toHaveBeenCalled(); - - act(() => { - hook.result.current.run(0).catch(e => e); - }); - expect(hook.result.current.loading).toEqual(true); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.error).toEqual(new Error('fail')); - expect(hook.result.current.loading).toEqual(false); - expect(errorCallback).toHaveBeenCalled(); - expect(successCallback).toHaveBeenCalled(); - - act(() => { - hook.result.current.run(1); - }); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.data).toEqual('success'); - expect(hook.result.current.loading).toEqual(false); - expect(errorCallback).toHaveBeenCalled(); - expect(successCallback).toHaveBeenCalledTimes(2); - - hook.unmount(); - }); - - it('hooks should be manually triggered', async () => { - const successCallback = jest.fn(); - const errorCallback = jest.fn(); - hook = renderHook(({ func, deps, opt }) => useAsync(func, deps, opt), { - initialProps: { - func: (req: number) => request(req), - deps: [] as ReadonlyArray<{}>, - opt: { - manual: true, - onSuccess: successCallback, - onError: errorCallback, - } as Options<{}>, - }, - }); - - const { run, loading } = hook.result.current; - expect(loading).toEqual(false); - act(() => { - run(1); - }); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.data).toEqual('success'); - expect(hook.result.current.loading).toEqual(false); - expect(errorCallback).not.toHaveBeenCalled(); - expect(successCallback).toHaveBeenCalled(); - - act(() => { - run(0).catch(e => e); - }); - expect(hook.result.current.loading).toEqual(true); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.error).toEqual(new Error('fail')); - expect(hook.result.current.loading).toEqual(false); - expect(errorCallback).toHaveBeenCalled(); - expect(successCallback).toHaveBeenCalled(); - - hook.unmount(); - }); - - it('timer should work with manual trigger', async () => { - const callback = jest.fn(); - - act(() => { - hook = renderHook(({ func, deps, opt }) => useAsync(func, deps, opt), { - initialProps: { - func: (req: number) => { - callback(); - return request(req); - }, - deps: [] as ReadonlyArray<{}>, - opt: { - manual: true, - pollingInterval: 3000, - } as Options<{}>, - }, - }); - }); - - expect(hook.result.current.loading).toEqual(false); - act(() => { - // start the timer - hook.result.current.run(); - }); - jest.runOnlyPendingTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.data).toEqual('success'); - expect(hook.result.current.loading).toEqual(false); - expect(callback).toHaveBeenCalled(); - - act(() => { - jest.runAllTimers(); - }); - await hook.waitForNextUpdate(); - expect(callback).toHaveBeenCalledTimes(2); - - jest.runAllTimers(); - // await hook.waitForNextUpdate(); - expect(callback).toHaveBeenCalledTimes(3); - - act(() => { - hook.result.current.timer.stop(); - }); - expect(callback).toHaveBeenCalledTimes(3); - - act(() => { - hook.result.current.timer.resume(); - }); - jest.runAllTimers(); - // await hook.waitForNextUpdate(); - expect(callback).toHaveBeenCalledTimes(4); - hook.unmount(); - }); - - it('timer should work with auto trigger', async () => { - const callback = jest.fn(); - hook = renderHook(({ func, deps, opt }) => useAsync(func, deps, opt), { - initialProps: { - func: (req: number) => { - callback(); - return request(req); - }, - deps: [] as ReadonlyArray<{}>, - opt: { - pollingInterval: 3000, - } as Options<{}>, - }, - }); - - expect(hook.result.current.loading).toEqual(true); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.data).toEqual('success'); - expect(hook.result.current.loading).toEqual(false); - expect(callback).toHaveBeenCalled(); - - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(callback).toHaveBeenCalledTimes(2); - - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(callback).toHaveBeenCalledTimes(3); - - act(() => { - hook.result.current.timer.pause(); - }); - expect(callback).toHaveBeenCalledTimes(3); - - act(() => { - hook.result.current.timer.resume(); - }); - jest.runAllTimers(); - // await hook.waitForNextUpdate(); - expect(callback).toHaveBeenCalledTimes(4); - hook.unmount(); - }); - - it('unmount hook in onSuccess callback', async () => { - const callback = jest.fn(); - let counter = 1; - hook = renderHook(({ func, deps, opt }) => useAsync(func, deps, opt), { - initialProps: { - func: (req: number) => request(req), - deps: [] as ReadonlyArray<{}>, - opt: { - onSuccess: () => { - if (counter === 1) { - counter += 1; - } else { - hook.unmount(); - } - }, - manual: true, - } as Options<{}>, - }, - }); - expect(hook.result.current.loading).toEqual(false); - - act(() => { - hook.result.current.run(1); - }); - jest.runAllTimers(); - await hook.waitForNextUpdate(); - expect(hook.result.current.data).toEqual('success'); - - act(() => { - hook.result.current.run(1).then(res => callback()); - }); - // hook already unmount - expect(callback).not.toHaveBeenCalled(); - }); -}); diff --git a/packages/hooks/src/useAsync/demo/demo1.tsx b/packages/hooks/src/useAsync/demo/demo1.tsx deleted file mode 100644 index 973cd93cff..0000000000 --- a/packages/hooks/src/useAsync/demo/demo1.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/** - * title: Default usage - * desc: Sending the request only when the "run" function is called, and will be re-executed after the deps change. - * - * title.zh-CN: 默认用法 - * desc.zh-CN: 组件加载时立即执行,并且 deps 变化后,会重新执行。 - */ - -import { useAsync } from '@umijs/hooks'; -import { Button, Spin } from 'antd'; -import React, { useState } from 'react'; - -function getNumber(id: number) { - return fetch(`https://helloacm.com/api/random/?n=8&x=4&id=${id}`).then(res => res.json()); -} - -export default () => { - const [state, set] = useState(0); - const { data, loading, cancel, run } = useAsync(() => getNumber(state), [state]); - - return ( - <> - -
id: {state}
-
Number: {data}
-
- - - - - - - ); -}; diff --git a/packages/hooks/src/useAsync/demo/demo2.tsx b/packages/hooks/src/useAsync/demo/demo2.tsx deleted file mode 100644 index 898259ba74..0000000000 --- a/packages/hooks/src/useAsync/demo/demo2.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/** - * title: Manually triggered - * desc: If manual is set, the async function only be executed when the "run" function is called. - * - * title.zh-CN: 手动触发执行 - * desc.zh-CN: 如果设置了 manual,则只有在执行函数 run 时,async function 才会被执行 - */ - -import { Button, Spin } from 'antd'; -import React from 'react'; -import { useAsync } from '@umijs/hooks'; - -function getNumber() { - return fetch('https://helloacm.com/api/random/?n=8&x=4').then(res => res.json()); -} - -export default () => { - const { data, loading, run } = useAsync(() => getNumber(), { manual: true }); - - return ( - <> - Number: {data} - - - ); -}; diff --git a/packages/hooks/src/useAsync/demo/demo3.tsx b/packages/hooks/src/useAsync/demo/demo3.tsx deleted file mode 100644 index fd0eb3d7cb..0000000000 --- a/packages/hooks/src/useAsync/demo/demo3.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/** - * title: Polling - * desc: If pollingInterval is set, Polling can be turned on, you can use `timer` to control the execution of async function. - * - * title.zh-CN: 轮询 - * desc.zh-CN: 可以通过设置 pollingInterval 来开启轮询功能,并且通过 timer 控制轮训的执行与停止。 - */ - -import { Button, Spin } from 'antd'; -import React from 'react'; -import { useAsync } from '@umijs/hooks'; - -function getNumber() { - return fetch('https://helloacm.com/api/random/?n=8&x=4').then(res => res.json()); -} - -export default () => { - const { data, loading, timer, run } = useAsync(() => getNumber(), [], { - manual: true, - pollingInterval: 3000, - }); - - return ( - <> - Number: {data} - - - - - - - - ); -}; diff --git a/packages/hooks/src/useAsync/demo/demo4.tsx b/packages/hooks/src/useAsync/demo/demo4.tsx deleted file mode 100644 index 613633feba..0000000000 --- a/packages/hooks/src/useAsync/demo/demo4.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/** - * title: Form Submission - * desc: A form submit example incorporate with antd form. - * - * title.zh-CN: 表单提交 - * desc.zh-CN: 配合 antd 表单提交的例子。 - */ - -import { Button, Form, Input, message } from 'antd'; -import { FormComponentProps } from 'antd/lib/form'; -import React from 'react'; -import { useAsync } from '@umijs/hooks'; - -const saveToServer = (data: string) => - new Promise(resolve => { - setTimeout(() => { - resolve(`${data} saved`); - }, 2000); - }); - -export default Form.create()((props: FormComponentProps) => { - const { loading, run } = useAsync(data => saveToServer(data), [], { - manual: true, - onSuccess: res => message.success(res), - onError: error => message.error(error), - }); - const { getFieldDecorator, getFieldValue } = props.form; - - const submit = () => { - const fromData = getFieldValue('name'); - run(fromData); - }; - - return ( - <> - {getFieldDecorator('name')( - , - )} - - - ); -}); diff --git a/packages/hooks/src/useAsync/index.en-US.md b/packages/hooks/src/useAsync/index.en-US.md deleted file mode 100644 index 98c7bb5d33..0000000000 --- a/packages/hooks/src/useAsync/index.en-US.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: useAsync -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /deprecated/use-async ---- - -# useAsync - - -⚠️WARNING: useAsync is deprecated and will be removed in the next major version. Please use useRequest instead. - - -A custom hook that helps you manage async functions and their returned data. - -## Examples - -### Default usage - - - -### Manually triggered - - - -### Polling - - - -### Form Submission - - - -## API - -```javascript -const result: Result = useAsync( - asyncFn: (value: any) => Promise, - options?: Options, -); - -const result: Result = useAsync( - asyncFn: (value: any) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -| Property | Description | Type | -|--------------|----------------------------------------------|---------------------------------| -| loading | whether the async function is resolved | boolean | -| params | the params you passed to that async function | any[] | -| error | the Error that async function throwed | Error | -| data | the result that async function resolved | any | -| cancel | drop the async function result | () => void | -| run | running the async function | (...args: any[]) => Promise | -| timer.stop | stop polling | () => void | -| timer.pause | pause pollinng | () => void | -| timer.resume | resume polling | () => void | - - -### Params - -| Property | Description | Type | Default | -|----------|-------------------------------------|------------------|----------------|--| -| service | the async function itself | (...args: Args \ | any)=> Promise | - | -| deps | dependencyList | any[] | [] | | -| options | advanced options,see Options below | - | - | | - -### Options - -| Property | Description | Type | Default | -|-----------------|------------------------------------------------------------------------------------|-----------------------------------|---------| -| manual | whether the function need to be triggered mannually | boolean | false | -| pollingInterval | the polling interval, enable polling only if this property is set. (numbers in ms) | number | - | -| onSuccess | the callback when async function runs successfully | (d: T, params: any[]) => void | - | -| onError | the callback when async function fails | (e: Error, params: any[]) => void | - | -| autoCancel | whether to drop the result when deps change or component unmount | boolean | true | diff --git a/packages/hooks/src/useAsync/index.ts b/packages/hooks/src/useAsync/index.ts deleted file mode 100644 index 14f4b1ba49..0000000000 --- a/packages/hooks/src/useAsync/index.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { DependencyList, useCallback, useState, useRef, useEffect } from 'react'; - -class Timer { - private remaining = 0; - - private delay = 0; - - private cb: ((...args: any[]) => Promise) | null = null; - - private start = 0; - - private timerId: any = 0; - - constructor(cb: () => Promise, delay: number) { - this.remaining = delay; - this.delay = delay; - this.start = Date.now(); - this.cb = cb; - } - - stop = () => { - clearTimeout(this.timerId); - this.timerId = 0; - this.remaining = this.delay; - }; - - pause = () => { - clearTimeout(this.timerId); - this.remaining -= Date.now() - this.start; - }; - - resume = () => { - this.start = Date.now(); - clearTimeout(this.timerId); - this.timerId = setTimeout(async () => { - if (this.cb) { - this.cb(); - } - }, this.remaining); - }; -} - -export interface Options { - manual?: boolean; // 是否初始化执行 - pollingInterval?: number; // 轮询的间隔毫秒 - onSuccess?: (data: T, params?: any[]) => void; // 成功回调 - onError?: (e: Error, params?: any[]) => void; // 失败回调 - autoCancel?: boolean; // 竞态处理开关 -} - -type noop = (...args: any[]) => void; -const noop: noop = () => { }; - -type promiseReturn = (...args: any[]) => Promise; -const promiseReturn: promiseReturn = async () => null as any; - -export interface ReturnValue { - loading: boolean; - error?: Error | string; - params: any[]; - data?: T; - cancel: noop; - run: promiseReturn; - timer: { - stop: noop; - resume: noop; - pause: noop; - }; -} -function useAsync( - fn: (...args: any[]) => Promise, - options?: Options, -): ReturnValue; -function useAsync( - fn: (...args: any[]) => Promise, - deps?: DependencyList, - options?: Options, -): ReturnValue; -function useAsync( - fn: (...args: any[]) => Promise, - deps?: DependencyList | Options, - options?: Options, -): ReturnValue { - const _deps: DependencyList = (Array.isArray(deps) ? deps : []) as DependencyList; - const _options: Options = (typeof deps === 'object' && !Array.isArray(deps) - ? deps - : options || {}) as Options; - - const params = useRef([]); - const { autoCancel = true } = _options; - const timer = useRef | undefined>(undefined); - const omitNextResume = useRef(false); - - const count = useRef(0); - const fnRef = useRef(fn); - fnRef.current = fn; - - const onSuccessRef = useRef(_options.onSuccess); - onSuccessRef.current = _options.onSuccess; - - const onErrorRef = useRef(_options.onError); - onErrorRef.current = _options.onError; - - // initial loading state is related to manual option - const [state, set] = useState({ - data: undefined as (Result | undefined), - error: undefined as (Error | string | undefined), - loading: !_options.manual, - }); - - const run = useCallback((...args: any[]): Promise => { - // 确保不会返回被取消的结果 - const runCount = count.current; - /* 当前参数保存一下 */ - params.current = args; - set(s => ({ ...s, loading: true })); - return fnRef - .current(...args) - .then(data => { - if (runCount === count.current) { - set(s => ({ ...s, data, loading: false })); - if (onSuccessRef.current) { - onSuccessRef.current(data, args || []); - } - } - return data; - }) - .catch(error => { - if (runCount === count.current) { - set(s => ({ ...s, error, loading: false })); - if (onErrorRef.current) { - onErrorRef.current(error, args || []); - } - } - throw error; - }); - }, []); - - /* 软取消,由于竞态,需要取消上一次的请求 */ - const softCancel = useCallback(() => { - if (autoCancel) { - count.current += 1; - set(s => ({ ...s, loading: false })); - } - }, [autoCancel]); - - /* 强制取消,组件卸载,或者用户手工取消 */ - const forceCancel = useCallback(() => { - count.current += 1; - set(s => ({ ...s, loading: false })); - }, []); - - const stop = useCallback(() => { - if (timer.current) { - timer.current.stop(); - omitNextResume.current = true; - } - forceCancel(); - }, [forceCancel]); - - const resume = useCallback(() => { - if (timer.current) { - omitNextResume.current = false; - timer.current.resume(); - } - }, []); - - const pause = useCallback(() => { - if (timer.current) { - timer.current.pause(); - omitNextResume.current = true; - } - forceCancel(); - }, [forceCancel]); - - const start = useCallback( - async (...args: any[]) => { - // 有定时器的延时逻辑 - if (_options.pollingInterval) { - if (timer.current) { - stop(); - } - omitNextResume.current = false; - timer.current = new Timer(() => start(...args), _options.pollingInterval as number); - const ret = run(...args); - ret.finally(() => { - if (timer.current && !omitNextResume.current) { - timer.current.resume(); - } - }); - return ret; - } - // 如果上一次异步操作还在 loading,则会尝试取消掉上一次的异步操作。 - softCancel(); - return run(...args); - }, - [run, softCancel, stop, _options.pollingInterval], - ); - - useEffect(() => { - if (!_options.manual) { - // deps 变化时,重新执行 - start(); - } - /* 如果 desp 变化,强制取消 */ - return () => { - if (timer.current) { - timer.current.stop(); - } - forceCancel(); - }; - }, [..._deps, forceCancel, start]); - - return { - loading: state.loading, - params: params.current, - error: state.error, - data: state.data, - cancel: forceCancel, - run: start, - timer: { - stop, - resume, - pause, - }, - }; -} - -export default useAsync; diff --git a/packages/hooks/src/useAsync/index.zh-CN.md b/packages/hooks/src/useAsync/index.zh-CN.md deleted file mode 100644 index 4505107a27..0000000000 --- a/packages/hooks/src/useAsync/index.zh-CN.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: useAsync -nav: - title: Hooks - path: /hooks -group: - title: 废弃 - path: /deprecated -legacy: /zh-CN/deprecated/use-api ---- - -# useAsync - - -⚠️警告: useAsync 已经被废弃了,将在下一个大版本时移除,你可以使用 useRequest 代替。 - - -一个帮你管理异步函数的 Hook,支持立即执行,手动触发执行,轮询。 - -## 代码演示 - -### 默认用法 - - - - -### 手动触发执行 - - - - -### 轮询 - - - - -### 表单提交 - - - - -## API - -```javascript -const result: Result = useAsync( - asyncFn: (value: any) => Promise, - options?: Options, -); - -const result: Result = useAsync( - asyncFn: (value: any) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -| 参数 | 说明 | 类型 | -|--------------|----------------------------|----------------------| -| loading | 是否正在加载 | boolean | -| params | 传给 async function 的参数 | any[] | -| error | 请求错误数据 | Error | -| data | 请求成功数据 | any | -| cancel | 取消 | () => void | -| run | 执行 | () => Promise | -| timer.stop | 轮询取消 | () => void | -| timer.pause | 轮询暂停 | () => void | -| timer.resume | 轮询继续 | () => void | - - -### 参数 - -| 参数 | 说明 | 类型 | 默认值 | | -|---------|------------------------|------------------|----------------|---| -| asyncFn | 异步请求函数 | (...args: Args \| any)=> Promise | - | -| deps | 依赖数组 | any[] | [] | | -| options | 可选配置项,见 Options | - | - | | - -### Options - -| 参数 | 说明 | 类型 | 默认值 | -|-----------------|--------------------------------------------------------|-----------------------------------|--------| -| manual | 是否需要手动触发 | boolean | false | -| pollingInterval | 轮询间隔毫秒,只有设置了 pollingInterval,才会开启轮询 | number | - | -| onSuccess | 执行成功时的回掉 | (d: T, params: any[]) => void | - | -| onError | 执行失败时的回掉 | (e: Error, params: any[]) => void | - | -| autoCancel | 是否需要关闭竞态处理 | boolean | true | diff --git a/packages/hooks/src/useBoolean/demo/demo1.tsx b/packages/hooks/src/useBoolean/demo/demo1.tsx index cd9250e062..0b9b3da56c 100644 --- a/packages/hooks/src/useBoolean/demo/demo1.tsx +++ b/packages/hooks/src/useBoolean/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button, Switch } from 'antd'; -import { useBoolean } from '@umijs/hooks'; +import { useBoolean } from 'ahooks'; export default () => { const { state, toggle, setTrue, setFalse } = useBoolean(true); diff --git a/packages/hooks/src/useClickAway/demo/demo1.tsx b/packages/hooks/src/useClickAway/demo/demo1.tsx index 34f79ad67e..806714cac6 100644 --- a/packages/hooks/src/useClickAway/demo/demo1.tsx +++ b/packages/hooks/src/useClickAway/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; -import {useClickAway} from '@umijs/hooks'; +import {useClickAway} from 'ahooks'; export default () => { const [counter, setCounter] = useState(0); diff --git a/packages/hooks/src/useClickAway/demo/demo2.tsx b/packages/hooks/src/useClickAway/demo/demo2.tsx index 95ac0145f8..5139b5703a 100644 --- a/packages/hooks/src/useClickAway/demo/demo2.tsx +++ b/packages/hooks/src/useClickAway/demo/demo2.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; -import {useClickAway} from '@umijs/hooks'; +import {useClickAway} from 'ahooks'; export default () => { const [counter, setCounter] = useState(0); diff --git a/packages/hooks/src/useControllableValue/demo/demo1.tsx b/packages/hooks/src/useControllableValue/demo/demo1.tsx index a1f84d6fa6..e9be312658 100644 --- a/packages/hooks/src/useControllableValue/demo/demo1.tsx +++ b/packages/hooks/src/useControllableValue/demo/demo1.tsx @@ -8,7 +8,7 @@ import { InputNumber } from 'antd'; import React from 'react'; -import { useControllableValue } from '@umijs/hooks' +import { useControllableValue } from 'ahooks' export default (props: any) => { const [state, setState] = useControllableValue(props, { diff --git a/packages/hooks/src/useControllableValue/demo/demo2.tsx b/packages/hooks/src/useControllableValue/demo/demo2.tsx index 9edce0c745..753c7dea8f 100644 --- a/packages/hooks/src/useControllableValue/demo/demo2.tsx +++ b/packages/hooks/src/useControllableValue/demo/demo2.tsx @@ -8,7 +8,7 @@ import { InputNumber, Button } from 'antd'; import React, { useState } from 'react'; -import { useControllableValue } from '@umijs/hooks'; +import { useControllableValue } from 'ahooks'; const ControllableComponent = (props: any) => { const [state, setState] = useControllableValue(props); diff --git a/packages/hooks/src/useControllableValue/demo/demo3.tsx b/packages/hooks/src/useControllableValue/demo/demo3.tsx index 2dcfe5dd37..b0b9a4903a 100644 --- a/packages/hooks/src/useControllableValue/demo/demo3.tsx +++ b/packages/hooks/src/useControllableValue/demo/demo3.tsx @@ -8,7 +8,7 @@ import { Input, Button } from 'antd'; import React, { useState } from 'react'; -import { useControllableValue } from '@umijs/hooks'; +import { useControllableValue } from 'ahooks'; const ControllableComponent = (props: any) => { const [state, setState] = useControllableValue(props); diff --git a/packages/hooks/src/useCounter/demo/demo1.tsx b/packages/hooks/src/useCounter/demo/demo1.tsx index 73e764f517..3fe1c27963 100644 --- a/packages/hooks/src/useCounter/demo/demo1.tsx +++ b/packages/hooks/src/useCounter/demo/demo1.tsx @@ -8,7 +8,7 @@ import { Button } from 'antd'; import React from 'react'; -import { useCounter } from '@umijs/hooks'; +import { useCounter } from 'ahooks'; export default () => { const [current, { inc, dec, set, reset }] = useCounter(100, { min: 1, max: 10 }); diff --git a/packages/hooks/src/useCreation/demo/demo1.tsx b/packages/hooks/src/useCreation/demo/demo1.tsx index c2bfc1ea44..d314df2328 100644 --- a/packages/hooks/src/useCreation/demo/demo1.tsx +++ b/packages/hooks/src/useCreation/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; -import { useCreation } from '@umijs/hooks'; +import { useCreation } from 'ahooks'; class Foo { constructor() { diff --git a/packages/hooks/src/useDebounce/demo/demo1.tsx b/packages/hooks/src/useDebounce/demo/demo1.tsx index b5b148b2d8..8f5da33304 100644 --- a/packages/hooks/src/useDebounce/demo/demo1.tsx +++ b/packages/hooks/src/useDebounce/demo/demo1.tsx @@ -8,7 +8,7 @@ import { Input } from 'antd'; import React, { useState } from 'react'; -import { useDebounce } from '@umijs/hooks'; +import { useDebounce } from 'ahooks'; export default () => { const [value, setValue] = useState(); diff --git a/packages/hooks/src/useDebounceFn/demo/demo1.tsx b/packages/hooks/src/useDebounceFn/demo/demo1.tsx index 4568ed575f..b815de600a 100644 --- a/packages/hooks/src/useDebounceFn/demo/demo1.tsx +++ b/packages/hooks/src/useDebounceFn/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; -import { useDebounceFn } from '@umijs/hooks'; +import { useDebounceFn } from 'ahooks'; export default () => { const [value, setValue] = useState(0); diff --git a/packages/hooks/src/useDebounceFn/demo/demo2.tsx b/packages/hooks/src/useDebounceFn/demo/demo2.tsx index c8b304d761..2c431944ee 100644 --- a/packages/hooks/src/useDebounceFn/demo/demo2.tsx +++ b/packages/hooks/src/useDebounceFn/demo/demo2.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button, Input } from 'antd'; -import { useDebounceFn } from '@umijs/hooks'; +import { useDebounceFn } from 'ahooks'; export default () => { const [value, setValue] = useState(); diff --git a/packages/hooks/src/useDocumentVisibility/demo/demo1.tsx b/packages/hooks/src/useDocumentVisibility/demo/demo1.tsx index fd56d5c6ad..e01223b92f 100644 --- a/packages/hooks/src/useDocumentVisibility/demo/demo1.tsx +++ b/packages/hooks/src/useDocumentVisibility/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React, { useEffect } from 'react'; -import { useDocumentVisibility } from '@umijs/hooks'; +import { useDocumentVisibility } from 'ahooks'; export default () => { const documentVisibility = useDocumentVisibility(); diff --git a/packages/hooks/src/useDrop/demo/demo1.tsx b/packages/hooks/src/useDrop/demo/demo1.tsx index ec7633bddc..b0d82d2845 100644 --- a/packages/hooks/src/useDrop/demo/demo1.tsx +++ b/packages/hooks/src/useDrop/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { message } from 'antd'; -import { useDrop, useDrag } from '@umijs/hooks'; +import { useDrop, useDrag } from 'ahooks'; export default () => { const getDragProps = useDrag(); diff --git a/packages/hooks/src/useDynamicList/demo/demo1.tsx b/packages/hooks/src/useDynamicList/demo/demo1.tsx index ba3fe67d2c..c353e67620 100644 --- a/packages/hooks/src/useDynamicList/demo/demo1.tsx +++ b/packages/hooks/src/useDynamicList/demo/demo1.tsx @@ -9,7 +9,7 @@ import React, { useState } from 'react'; import { Form, Button, Input, Icon } from 'antd'; import { FormComponentProps } from 'antd/lib/form'; -import { useDynamicList } from '@umijs/hooks' +import { useDynamicList } from 'ahooks' export default Form.create()((props: FormComponentProps) => { const { list, remove, getKey, push } = useDynamicList(['David', 'Jack']); diff --git a/packages/hooks/src/useDynamicList/demo/demo2.tsx b/packages/hooks/src/useDynamicList/demo/demo2.tsx index d055f87fd1..6b9384b984 100644 --- a/packages/hooks/src/useDynamicList/demo/demo2.tsx +++ b/packages/hooks/src/useDynamicList/demo/demo2.tsx @@ -9,7 +9,7 @@ import React, { useState } from 'react'; import { Form, Input, Button } from 'antd'; import { FormComponentProps } from 'antd/lib/form'; -import { useDynamicList } from '@umijs/hooks'; +import { useDynamicList } from 'ahooks'; interface CardProps extends FormComponentProps { index: number; diff --git a/packages/hooks/src/useDynamicList/demo/demo3.tsx b/packages/hooks/src/useDynamicList/demo/demo3.tsx index 04cc3948a1..22bb3029af 100644 --- a/packages/hooks/src/useDynamicList/demo/demo3.tsx +++ b/packages/hooks/src/useDynamicList/demo/demo3.tsx @@ -10,7 +10,7 @@ import React, { useState } from 'react'; import { Form, Button, Input, Icon, Table } from 'antd'; import { FormComponentProps } from 'antd/lib/form'; import ReactDragListView from 'react-drag-listview'; -import { useDynamicList } from '@umijs/hooks'; +import { useDynamicList } from 'ahooks'; interface Item { name?: string; diff --git a/packages/hooks/src/useEventEmitter/demo/demo1.tsx b/packages/hooks/src/useEventEmitter/demo/demo1.tsx index 858c2fdce3..a1aea51b25 100644 --- a/packages/hooks/src/useEventEmitter/demo/demo1.tsx +++ b/packages/hooks/src/useEventEmitter/demo/demo1.tsx @@ -8,8 +8,8 @@ import React, { useRef, FC } from 'react'; import { Button, Input } from 'antd'; -import { useEventEmitter } from '@umijs/hooks'; -import { EventEmitter } from '@umijs/hooks/lib/useEventEmitter' +import { useEventEmitter } from 'ahooks'; +import { EventEmitter } from 'ahooks/lib/useEventEmitter' const MessageBox: FC<{ focus$: EventEmitter; diff --git a/packages/hooks/src/useEventTarget/demo/demo1.tsx b/packages/hooks/src/useEventTarget/demo/demo1.tsx index 5b93aba339..9b41fb2832 100644 --- a/packages/hooks/src/useEventTarget/demo/demo1.tsx +++ b/packages/hooks/src/useEventTarget/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { Fragment } from 'react'; import { Input, Button } from 'antd'; -import { useEventTarget } from '@umijs/hooks' +import { useEventTarget } from 'ahooks' export default () => { const [valueProps, reset] = useEventTarget('this is initial value'); diff --git a/packages/hooks/src/useEventTarget/demo/demo2.tsx b/packages/hooks/src/useEventTarget/demo/demo2.tsx index 08190c3fb9..c03b30081e 100644 --- a/packages/hooks/src/useEventTarget/demo/demo2.tsx +++ b/packages/hooks/src/useEventTarget/demo/demo2.tsx @@ -7,7 +7,7 @@ import React, { Fragment } from 'react'; import { Input, Button } from 'antd'; -import { useEventTarget } from '@umijs/hooks' +import { useEventTarget } from 'ahooks' export default () => { const [valueProps, reset] = useEventTarget('', (val: string) => { diff --git a/packages/hooks/src/useFormTable/demo/demo1.tsx b/packages/hooks/src/useFormTable/demo/demo1.tsx index a1b270353f..f58eb1402b 100644 --- a/packages/hooks/src/useFormTable/demo/demo1.tsx +++ b/packages/hooks/src/useFormTable/demo/demo1.tsx @@ -1,16 +1,16 @@ /** * title: Form and Table data binding - * desc: useFormTable returns a search object after receiving a form instance. This is an example of antd v3, see [link](https://github.com/umijs/hooks/blob/master/packages/hooks/src/useFormTable/demo/demo3.tsx) for an example of antd v4. + * desc: useFormTable returns a search object after receiving a form instance. This is an example of antd v3, see [link](https://github.com/ice-lab/ahooks/blob/master/packages/hooks/src/useFormTable/demo/demo3.tsx) for an example of antd v4. * * title.zh-CN: Form 与 Table 联动 - * desc.zh-CN: useFormTable 接收 form 实例后,会返回 search 对象。这是一个 antd v3 示例,antd v4 示例见 [链接](https://github.com/umijs/hooks/blob/master/packages/hooks/src/useFormTable/demo/demo3.tsx)。 + * desc.zh-CN: useFormTable 接收 form 实例后,会返回 search 对象。这是一个 antd v3 示例,antd v4 示例见 [链接](https://github.com/ice-lab/ahooks/blob/master/packages/hooks/src/useFormTable/demo/demo3.tsx)。 */ import React from 'react'; import { Button, Col, Form, Input, Row, Table, Select } from 'antd'; import { WrappedFormUtils } from 'antd/lib/form/Form'; -import { useFormTable } from '@umijs/hooks' -import { PaginatedParams } from '@umijs/hooks/lib/useFormTable' +import { useFormTable } from 'ahooks' +import { PaginatedParams } from 'ahooks/lib/useFormTable' const { Option } = Select; diff --git a/packages/hooks/src/useFormTable/demo/demo2.tsx b/packages/hooks/src/useFormTable/demo/demo2.tsx index 72e7989643..851804aecb 100644 --- a/packages/hooks/src/useFormTable/demo/demo2.tsx +++ b/packages/hooks/src/useFormTable/demo/demo2.tsx @@ -1,16 +1,16 @@ /** * title: Data caching - * desc: Form and Table data cache through cacheKey. This is an example of antd v3, see [link](https://github.com/umijs/hooks/blob/master/packages/hooks/src/useFormTable/demo/demo4.tsx) for an example of antd v4. + * desc: Form and Table data cache through cacheKey. This is an example of antd v3, see [link](https://github.com/ice-lab/ahooks/blob/master/packages/hooks/src/useFormTable/demo/demo4.tsx) for an example of antd v4. * * title.zh-CN: 数据缓存 - * desc.zh-CN: 通过 cacheKey 可以实现 Form 和 Table 数据缓存。这是一个 antd v3 示例,antd v4 示例见 [链接](https://github.com/umijs/hooks/blob/master/packages/hooks/src/useFormTable/demo/demo4.tsx)。 + * desc.zh-CN: 通过 cacheKey 可以实现 Form 和 Table 数据缓存。这是一个 antd v3 示例,antd v4 示例见 [链接](https://github.com/ice-lab/ahooks/blob/master/packages/hooks/src/useFormTable/demo/demo4.tsx)。 */ import { Button, Form, Input, Table } from 'antd'; import React, { useState } from 'react'; import { WrappedFormUtils } from 'antd/lib/form/Form'; -import { useFormTable } from '@umijs/hooks' -import { PaginatedParams } from '@umijs/hooks/lib/useFormTable' +import { useFormTable } from 'ahooks' +import { PaginatedParams } from 'ahooks/lib/useFormTable' interface Item { name: { diff --git a/packages/hooks/src/useFormTable/demo/demo3.tsx b/packages/hooks/src/useFormTable/demo/demo3.tsx index 9b5af7e5e3..b5bac2ddde 100644 --- a/packages/hooks/src/useFormTable/demo/demo3.tsx +++ b/packages/hooks/src/useFormTable/demo/demo3.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { Button, Col, Form, Input, Row, Table, Select } from 'antd'; -import { useFormTable } from '@umijs/hooks' -import { PaginatedParams } from '@umijs/hooks/lib/useFormTable' +import { useFormTable } from 'ahooks' +import { PaginatedParams } from 'ahooks/lib/useFormTable' const { Option } = Select; diff --git a/packages/hooks/src/useFormTable/demo/demo4.tsx b/packages/hooks/src/useFormTable/demo/demo4.tsx index 11f9bd2c4f..f452b1d966 100644 --- a/packages/hooks/src/useFormTable/demo/demo4.tsx +++ b/packages/hooks/src/useFormTable/demo/demo4.tsx @@ -6,8 +6,8 @@ * desc.zh-CN: 通过 cacheKey 可以实现 Form 和 Table 数据缓存。这是一个 antd v3 示例,antd v4 示例见 [链接](href)。 */ -import { useFormTable } from '@umijs/hooks'; -import { PaginatedParams } from '@umijs/hooks/lib/useFormTable'; +import { useFormTable } from 'ahooks'; +import { PaginatedParams } from 'ahooks/lib/useFormTable'; import { Button, Form, Input, Table } from 'antd'; import React, { useState } from 'react'; diff --git a/packages/hooks/src/useFormTable/demo/demo5.tsx b/packages/hooks/src/useFormTable/demo/demo5.tsx index cc26563a6c..acd4314112 100644 --- a/packages/hooks/src/useFormTable/demo/demo5.tsx +++ b/packages/hooks/src/useFormTable/demo/demo5.tsx @@ -12,8 +12,8 @@ import React from 'react'; import { Button, Col, Form, Input, Row, Table, Select } from 'antd'; import { WrappedFormUtils } from 'antd/lib/form/Form'; -import { useFormTable } from '@umijs/hooks' -import { PaginatedParams } from '@umijs/hooks/lib/useFormTable' +import { useFormTable } from 'ahooks' +import { PaginatedParams } from 'ahooks/lib/useFormTable' const { Option } = Select; diff --git a/packages/hooks/src/useFormTable/index.ts b/packages/hooks/src/useFormTable/index.ts index 6b93c04f0b..01ea9ed7a0 100644 --- a/packages/hooks/src/useFormTable/index.ts +++ b/packages/hooks/src/useFormTable/index.ts @@ -1,4 +1,4 @@ -import useRequest from '@umijs/use-request'; +import useRequest from '@ahooksjs/use-request'; import { useState, useCallback, useEffect, useRef } from 'react'; import { CombineService, @@ -7,7 +7,7 @@ import { PaginatedOptionsWithFormat, PaginatedFormatReturn, PaginatedResult -} from '@umijs/use-request/lib/types'; +} from '@ahooksjs/use-request/lib/types'; import useUpdateEffect from '../useUpdateEffect'; import usePersistFn from '../usePersistFn'; diff --git a/packages/hooks/src/useFullscreen/demo/demo1.tsx b/packages/hooks/src/useFullscreen/demo/demo1.tsx index b5376a4e8f..8c473abbfc 100644 --- a/packages/hooks/src/useFullscreen/demo/demo1.tsx +++ b/packages/hooks/src/useFullscreen/demo/demo1.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { Button } from 'antd'; -import {useFullscreen} from '@umijs/hooks'; +import {useFullscreen} from 'ahooks'; export default () => { const { ref, isFullscreen, setFull, exitFull, toggleFull } = useFullscreen(); diff --git a/packages/hooks/src/useFullscreen/demo/demo2.tsx b/packages/hooks/src/useFullscreen/demo/demo2.tsx index 14ec7019e9..2dc2abf0dc 100644 --- a/packages/hooks/src/useFullscreen/demo/demo2.tsx +++ b/packages/hooks/src/useFullscreen/demo/demo2.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button } from 'antd'; -import {useFullscreen} from '@umijs/hooks'; +import {useFullscreen} from 'ahooks'; import img from './react-hooks.jpg'; export default () => { diff --git a/packages/hooks/src/useHistoryTravel/demo/demo1.tsx b/packages/hooks/src/useHistoryTravel/demo/demo1.tsx index a1ca2ecb94..1316340256 100644 --- a/packages/hooks/src/useHistoryTravel/demo/demo1.tsx +++ b/packages/hooks/src/useHistoryTravel/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Input, Button, List, InputNumber } from 'antd'; -import { useEventTarget, useHistoryTravel } from '@umijs/hooks'; +import { useEventTarget, useHistoryTravel } from 'ahooks'; const { Item } = List; diff --git a/packages/hooks/src/useHover/demo/demo1.tsx b/packages/hooks/src/useHover/demo/demo1.tsx index 4dd1939140..a436106008 100644 --- a/packages/hooks/src/useHover/demo/demo1.tsx +++ b/packages/hooks/src/useHover/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import { useHover } from '@umijs/hooks'; +import { useHover } from 'ahooks'; export default () => { const [isHovering, hoverRef] = useHover(); diff --git a/packages/hooks/src/useHover/demo/demo2.tsx b/packages/hooks/src/useHover/demo/demo2.tsx index a16f138c11..0eb03e410f 100644 --- a/packages/hooks/src/useHover/demo/demo2.tsx +++ b/packages/hooks/src/useHover/demo/demo2.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import { useHover } from '@umijs/hooks'; +import { useHover } from 'ahooks'; export default () => { const [isHovering] = useHover({ diff --git a/packages/hooks/src/useInViewport/demo/demo1.tsx b/packages/hooks/src/useInViewport/demo/demo1.tsx index bd477b1889..6c71d924cd 100644 --- a/packages/hooks/src/useInViewport/demo/demo1.tsx +++ b/packages/hooks/src/useInViewport/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import {useInViewport} from '@umijs/hooks'; +import {useInViewport} from 'ahooks'; export default () => { const [inViewPort, ref] = useInViewport(); diff --git a/packages/hooks/src/useInViewport/demo/demo2.tsx b/packages/hooks/src/useInViewport/demo/demo2.tsx index aaf7d44896..fbffdab5cb 100644 --- a/packages/hooks/src/useInViewport/demo/demo2.tsx +++ b/packages/hooks/src/useInViewport/demo/demo2.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import {useInViewport} from '@umijs/hooks'; +import {useInViewport} from 'ahooks'; export default () => { const [inViewPort] = useInViewport(() => document.querySelector('#demo2')); diff --git a/packages/hooks/src/useKeyPress/demo/demo1.tsx b/packages/hooks/src/useKeyPress/demo/demo1.tsx index 7e459a5958..5294e4d588 100644 --- a/packages/hooks/src/useKeyPress/demo/demo1.tsx +++ b/packages/hooks/src/useKeyPress/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React, { useState } from 'react'; -import {useKeyPress} from '@umijs/hooks'; +import {useKeyPress} from 'ahooks'; export default () => { const [counter, setCounter] = useState(0); diff --git a/packages/hooks/src/useKeyPress/demo/demo2.tsx b/packages/hooks/src/useKeyPress/demo/demo2.tsx index 6b5b470701..b1bd83c2f1 100644 --- a/packages/hooks/src/useKeyPress/demo/demo2.tsx +++ b/packages/hooks/src/useKeyPress/demo/demo2.tsx @@ -7,7 +7,7 @@ */ import React, { useState } from 'react'; -import {useKeyPress} from '@umijs/hooks'; +import {useKeyPress} from 'ahooks'; export default () => { const [counter, setCounter] = useState(0); diff --git a/packages/hooks/src/useKeyPress/demo/demo3.tsx b/packages/hooks/src/useKeyPress/demo/demo3.tsx index 77699ee576..fd9c289662 100644 --- a/packages/hooks/src/useKeyPress/demo/demo3.tsx +++ b/packages/hooks/src/useKeyPress/demo/demo3.tsx @@ -14,7 +14,7 @@ import React, { useState } from 'react'; import { Icon } from 'antd'; -import {useKeyPress} from '@umijs/hooks'; +import {useKeyPress} from 'ahooks'; export default () => { const [num, setNum] = useState(); diff --git a/packages/hooks/src/useKeyPress/demo/demo4.tsx b/packages/hooks/src/useKeyPress/demo/demo4.tsx index 65c40e41fd..11ee9fe2a7 100644 --- a/packages/hooks/src/useKeyPress/demo/demo4.tsx +++ b/packages/hooks/src/useKeyPress/demo/demo4.tsx @@ -7,7 +7,7 @@ */ import React, { useState } from 'react'; -import {useKeyPress} from '@umijs/hooks'; +import {useKeyPress} from 'ahooks'; export default () => { const [key, setKey] = useState(); diff --git a/packages/hooks/src/useKeyPress/demo/demo5.tsx b/packages/hooks/src/useKeyPress/demo/demo5.tsx index 97e627eda3..e267b9da69 100644 --- a/packages/hooks/src/useKeyPress/demo/demo5.tsx +++ b/packages/hooks/src/useKeyPress/demo/demo5.tsx @@ -13,7 +13,7 @@ */ import React, { useState } from 'react'; -import {useKeyPress} from '@umijs/hooks'; +import {useKeyPress} from 'ahooks'; export default () => { const [text, setText] = useState(''); diff --git a/packages/hooks/src/useLoadMore/__tests__/index.test.ts b/packages/hooks/src/useLoadMore/__tests__/index.test.ts deleted file mode 100644 index 7ad5e2370e..0000000000 --- a/packages/hooks/src/useLoadMore/__tests__/index.test.ts +++ /dev/null @@ -1,310 +0,0 @@ -import { renderHook, act } from '@testing-library/react-hooks'; -import useLoadMore from '../index'; - -/* 暂时关闭 act 警告 见:https://github.com/testing-library/react-testing-library/issues/281#issuecomment-480349256 */ -const originalError = console.error; -beforeAll(() => { - console.error = (...args: any) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return; - } - originalError.call(console, ...args); - }; -}); - -afterAll(() => { - console.error = originalError; -}); - -const dataSrouce = [ - { - id: 1, - title: 'Ant Design Title 1', - }, - { - id: 2, - title: 'Ant Design Title 2', - }, - { - id: 3, - title: 'Ant Design Title 3', - }, - { - id: 4, - title: 'Ant Design Title 4', - }, - { - id: 5, - title: 'Ant Design Title 5', - }, - { - id: 6, - title: 'Ant Design Title 6', - }, - { - id: 7, - title: 'Ant Design Title 7', - }, - { - id: 8, - title: 'Ant Design Title 8', - }, - { - id: 9, - title: 'Ant Design Title 9', - }, - { - id: 10, - title: 'Ant Design Title 10', - }, -]; - -const asyncFn = ({ pageSize, offset }: any) => - new Promise(resolve => { - setTimeout(() => { - const data = - pageSize === -1 - ? null - : { - total: dataSrouce.length, - data: dataSrouce.slice(offset, offset + pageSize), - }; - resolve(data); - }, 1); - }); - -const callLoadmore = (hook: any) => { - act(() => { - const { loadMore } = hook.result.current; - loadMore(); - }); -}; - -const callReload = (hook: any) => { - act(() => { - const { reload } = hook.result.current; - reload(); - }); -}; - -describe('useLoadMore', () => { - it('should be defined', () => { - expect(useLoadMore).toBeDefined(); - }); - - describe('render the first', () => { - let hook: any; - beforeEach(() => { - hook = renderHook(() => - useLoadMore(asyncFn, undefined, { - initPageSize: 3, - }), - ); - }); - - it('initially starts loading', () => { - expect(hook.result.current.loading).toBeTruthy(); - }); - - it('resolves', async () => { - expect.assertions(3); - - const { rerender, waitForNextUpdate } = hook; - rerender(); - await waitForNextUpdate(); - const { data, total, loading } = hook.result.current; - expect(data.length).toEqual(3); - expect(total).toEqual(10); - expect(loading).toBeFalsy(); - }); - }); - - describe('should method run', () => { - let hook: any; - beforeEach(done => { - hook = renderHook(({ fn, deps, options }) => useLoadMore(fn, [deps], options), { - initialProps: { - fn: asyncFn, - deps: null, - options: { - itemKey: 'id', - initPageSize: 3, - incrementSize: 4, - }, - }, - }); - - hook.waitForNextUpdate().then(done); - }); - - it('test on loadmore', async () => { - expect.assertions(5); - - callLoadmore(hook); - expect(hook.result.current.loadingMore).toBeTruthy(); - await hook.waitForNextUpdate(); - expect(hook.result.current.loadingMore).toBeFalsy(); - expect(hook.result.current.data.length).toEqual(7); - - callLoadmore(hook); - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(10); - expect(hook.result.current.noMore).toBeTruthy(); - }); - - it('test on reload', async () => { - expect.assertions(6); - - hook.rerender({ - fn: asyncFn, - deps: [], - options: { - initPageSize: 4, - itemKey: (item: any, index: any) => undefined, - }, - }); - - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(4); - - callLoadmore(hook); - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(8); - - callLoadmore(hook); - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(10); - - // 测试边界值 - callLoadmore(hook); - - callReload(hook); - expect(hook.result.current.loading).toBeTruthy(); - await hook.waitForNextUpdate(); - expect(hook.result.current.loadingMore).toBeFalsy(); - expect(hook.result.current.data.length).toEqual(4); - }); - }); - - describe('the additional dependencies list changes', () => { - const result = [ - { - id: 1222, - title: 'hahaha', - }, - ]; - - let callCount = 0; - // 模拟一个dom对象 - const ref = { - current: { - scrollHeight: 800, - scrollTop: 0, - clientHeight: 200, - addEventListener(trigger: any, callback: any) { - callCount = 1; - callback(); - }, - removeEventListener(trigger: any, callback: any) { - callCount = 2; - callback(); - }, - }, - }; - - let hook: any; - beforeEach(done => { - callCount = 0; - hook = renderHook(({ fn, deps, options }) => useLoadMore(fn, [deps], options), { - initialProps: { - fn: asyncFn, - deps: null, - options: { - initPageSize: 3, - incrementSize: 4, - threshold: 100, - }, - }, - }); - hook.waitForNextUpdate().then(done); - }); - - it('test on different options', async () => { - // expect.assertions(2); - - hook.rerender({ - fn: asyncFn, - deps: [], - options: { - initPageSize: 6, - threshold: 200, - itemKey: (item: any, index: any) => 'id', - formatResult: (res: any) => ({ - total: 0, - data: result, - }), - }, - }); - await hook.waitForNextUpdate(); - - expect(hook.result.current.data).toEqual(result); - expect(hook.result.current.total).toEqual(0); - - // 测试边界溢出 - hook.rerender({ - fn: asyncFn, - deps: [], - options: { - initPageSize: -1, - incrementSize: -1, - threshold: 200, - itemKey: (item: any, index: any) => 'id', - formatResult: (res: any) => ({ - total: 0, - data: result, - }), - }, - }); - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(0); - }); - - it('test on dom scroll', async () => { - expect(hook.result.current.data.length).toEqual(3); - expect(hook.result.current.noMore).toBeFalsy(); - - ref.current.scrollTop = 100; - - hook.rerender({ - fn: asyncFn, - deps: [], - options: { - initPageSize: 6, - threshold: 100, - ref, - }, - }); - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(6); - expect(hook.result.current.noMore).toBeFalsy(); - - ref.current.scrollTop = 600; - - hook.rerender({ - fn: asyncFn, - deps: [], - options: { - initPageSize: 10, - threshold: 100, - ref, - }, - }); - await hook.waitForNextUpdate(); - expect(hook.result.current.data.length).toEqual(10); - expect(hook.result.current.noMore).toBeTruthy(); - - hook.unmount(); - expect(callCount).toEqual(2); - }); - }); -}); diff --git a/packages/hooks/src/useLoadMore/demo/demo1.tsx b/packages/hooks/src/useLoadMore/demo/demo1.tsx deleted file mode 100644 index 51f600da1d..0000000000 --- a/packages/hooks/src/useLoadMore/demo/demo1.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/** - * title: Click to load more - * desc: Standard loading more examples. - * - * title.zh-CN: 点击加载更多 - * desc.zh-CN: 标准的加载更多例子 - */ - -import { useLoadMore } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/useLoadMore'; -import { Avatar, Button, List } from 'antd'; -import React from 'react'; - -interface Item { - id: number; - title: string; -} -interface Result { - total: number; - data: Item[]; -} - -const dataSource = [ - { - id: 1, - title: 'Ant Design Title 1', - }, - { - id: 2, - title: 'Ant Design Title 2', - }, - { - id: 3, - title: 'Ant Design Title 3', - }, - { - id: 4, - title: 'Ant Design Title 4', - }, - { - id: 5, - title: 'Ant Design Title 5', - }, - { - id: 6, - title: 'Ant Design Title 6', - }, - { - id: 7, - title: 'Ant Design Title 7', - }, - { - id: 8, - title: 'Ant Design Title 8', - }, - { - id: 9, - title: 'Ant Design Title 9', - }, - { - id: 10, - title: 'Ant Design Title 10', - }, -]; - -const asyncFn = ({ pageSize, offset }: FnParams): Promise => - new Promise(resolve => { - setTimeout(() => { - resolve({ - total: dataSource.length, - data: dataSource.slice(offset, offset + pageSize), - }); - }, 1000); - }); - -export default () => { - const { data, loading, loadingMore, reload, loadMore, total, noMore } = useLoadMore( - asyncFn, - { - initPageSize: 3, - incrementSize: 4, - }, - ); - - const renderFooter = () => ( - <> - {!noMore && ( - - )} - - {noMore && No more data} - - total: {total} - - ); - - return ( -
- - Reload - - } - footer={!loading && renderFooter()} - loading={loading} - bordered - dataSource={data} - renderItem={item => ( - - - } - title={{item.title}} - description="umijs/hooks is a react hooks library" - /> - - )} - /> -
- ); -}; diff --git a/packages/hooks/src/useLoadMore/demo/demo2.tsx b/packages/hooks/src/useLoadMore/demo/demo2.tsx deleted file mode 100644 index 03308ab6e5..0000000000 --- a/packages/hooks/src/useLoadMore/demo/demo2.tsx +++ /dev/null @@ -1,127 +0,0 @@ -/** - * title: Pull up to load more - * desc: If ref exists in options, loadMore is automatically triggered when scrolling to the bottom. - * - * title.zh-CN: 上拉加载更多 - * desc.zh-CN: 如果 options 中存在 ref,则在滚动到底部时,自动触发 loadMore。 - */ - -import { List, Button, Avatar } from 'antd'; -import React, { useRef } from 'react'; -import { useLoadMore } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/useLoadMore'; - -interface Item { - id: number; - title: string; -} -interface Result { - total: number; - data: Item[]; -} - -const dataSource = [ - { - id: 1, - title: 'Ant Design Title 1', - }, - { - id: 2, - title: 'Ant Design Title 2', - }, - { - id: 3, - title: 'Ant Design Title 3', - }, - { - id: 4, - title: 'Ant Design Title 4', - }, - { - id: 5, - title: 'Ant Design Title 5', - }, - { - id: 6, - title: 'Ant Design Title 6', - }, - { - id: 7, - title: 'Ant Design Title 7', - }, - { - id: 8, - title: 'Ant Design Title 8', - }, - { - id: 9, - title: 'Ant Design Title 9', - }, - { - id: 10, - title: 'Ant Design Title 10', - }, -]; - -const asyncFn = ({ pageSize, offset }: FnParams): Promise => - new Promise(resolve => { - setTimeout(() => { - resolve({ - total: dataSource.length, - data: dataSource.slice(offset, offset + pageSize), - }); - }, 1000); - }); - -export default () => { - const containerRef = useRef(null); - const { data, loading, loadingMore, reload, loadMore, total, noMore } = useLoadMore( - asyncFn, - { - ref: containerRef, - initPageSize: 3, - incrementSize: 4, - }, - ); - - const renderFooter = () => ( - <> - {!noMore && ( - - )} - - {noMore && No more data} - - total: {total} - - ); - - return ( -
- - Reload - - } - footer={!loading && renderFooter()} - loading={loading} - bordered - dataSource={data} - renderItem={item => ( - - - } - title={{item.title}} - description="umijs/hooks is a react hooks library" - /> - - )} - /> -
- ); -}; diff --git a/packages/hooks/src/useLoadMore/demo/demo3.tsx b/packages/hooks/src/useLoadMore/demo/demo3.tsx deleted file mode 100644 index 0360fa3336..0000000000 --- a/packages/hooks/src/useLoadMore/demo/demo3.tsx +++ /dev/null @@ -1,137 +0,0 @@ -/** - * title: use deps properly - * desc: If the deps changes, reset the current page and re-request the data. - * - * title.zh-CN: 合理利用 deps - * desc.zh-CN: 如果 deps 变化,则重置当前分页,重新请求数据。 - */ - -import { List, Button, Avatar, Select } from 'antd'; -import React, { useState } from 'react'; -import { useLoadMore } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/useLoadMore'; - -const { Option } = Select; - -interface Item { - id: number; - title: string; -} -interface Result { - total: number; - data: Item[]; -} - -interface Params extends FnParams { - gender: 'male' | 'female'; -} - -const dataSource = [ - { - id: 1, - title: 'Ant Design Title 1', - }, - { - id: 2, - title: 'Ant Design Title 2', - }, - { - id: 3, - title: 'Ant Design Title 3', - }, - { - id: 4, - title: 'Ant Design Title 4', - }, - { - id: 5, - title: 'Ant Design Title 5', - }, - { - id: 6, - title: 'Ant Design Title 6', - }, - { - id: 7, - title: 'Ant Design Title 7', - }, - { - id: 8, - title: 'Ant Design Title 8', - }, - { - id: 9, - title: 'Ant Design Title 9', - }, - { - id: 10, - title: 'Ant Design Title 10', - }, -]; - -const asyncFn = ({ pageSize, offset, gender }: Params): Promise => - new Promise(resolve => { - setTimeout(() => { - resolve({ - total: dataSource.length, - data: dataSource.slice(offset, offset + pageSize), - }); - }, 1000); - }); - -export default () => { - const [gender, setGender] = useState<'male' | 'female'>('male'); - const { data, loading, loadingMore, loadMore, total, noMore } = useLoadMore( - params => asyncFn({ ...params, gender }), - [gender], - { - initPageSize: 3, - incrementSize: 4, - }, - ); - - const renderFooter = () => ( - <> - {!noMore && ( - - )} - - {noMore && No more data} - - total: {total} - - ); - - return ( -
- - Filter Gender: - - - } - footer={!loading && renderFooter()} - loading={loading} - bordered - dataSource={data} - renderItem={item => ( - - - } - title={{item.title}} - description="umijs/hooks is a react hooks library" - /> - - )} - /> -
- ); -}; diff --git a/packages/hooks/src/useLoadMore/demo/demo4.tsx b/packages/hooks/src/useLoadMore/demo/demo4.tsx deleted file mode 100644 index fa49716ba8..0000000000 --- a/packages/hooks/src/useLoadMore/demo/demo4.tsx +++ /dev/null @@ -1,142 +0,0 @@ -/** - * title: custom data loading - timestamp mode - * desc: If the back-end data is constantly being updated, then just use page, offset, pageSize, etc. to cut the data, and there may be a lot of duplicate data. At this time, if we know the time to pull the data for the first time, then only the data before this timestamp can be cut at the same time, and the correct data can be obtained. - * - * We will record the current time 'startTime' when we first start the request or reload, and pass it to asyncFn. - * - * title.zh-CN: 动态数据加载之时间戳模式 - * desc.zh-CN: 如果后端数据在不断更新,那么仅仅使用 page, offset, pageSize 等来切割数据,可能会出现很多的重复的数据。这时候如果我们知道第一次拉取数据的时间,那每次只对这个时间戳之前的数据进行切割,是可以拿到正确数据的。 - * - * 我们会记录在第一次开始请求或 reload 时,记录当前的时间 startTime,并把它传给 asyncFn。 - */ - -import { List, Button, Avatar } from 'antd'; -import React from 'react'; -import { useLoadMore } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/useLoadMore'; - -interface Item { - id: number; - title: string; -} -interface Result { - total: number; - data: Item[]; -} - -const dataSource = [ - { - id: 1, - title: 'Ant Design Title 1', - createTime: 1572783081, - }, - { - id: 2, - title: 'Ant Design Title 2', - createTime: 1572783082, - }, - { - id: 3, - title: 'Ant Design Title 3', - createTime: 1572783083, - }, - { - id: 4, - title: 'Ant Design Title 4', - createTime: 1572783084, - }, - { - id: 5, - title: 'Ant Design Title 5', - createTime: 1572783085, - }, - { - id: 6, - title: 'Ant Design Title 6', - createTime: 1572783086, - }, - { - id: 7, - title: 'Ant Design Title 7', - createTime: 1572783087, - }, - { - id: 8, - title: 'Ant Design Title 8', - createTime: 1572783088, - }, - { - id: 9, - title: 'Ant Design Title 9', - createTime: 1572783089, - }, - { - id: 10, - title: 'Ant Design Title 10', - createTime: 1572783090, - }, -]; - -const asyncFn = ({ pageSize, offset, startTime }: FnParams): Promise => { - /* should query data by timestamp */ - const filteredData = dataSource.filter(i => i.createTime <= startTime); - return new Promise(resolve => { - setTimeout(() => { - resolve({ - total: filteredData.length, - data: filteredData.slice(offset, offset + pageSize), - }); - }, 1000); - }); -}; - -export default () => { - const { data, loading, loadingMore, reload, loadMore, total, noMore } = useLoadMore( - asyncFn, - { - initPageSize: 3, - incrementSize: 4, - }, - ); - - const renderFooter = () => ( - <> - {!noMore && ( - - )} - - {noMore && No more data} - - total: {total} - - ); - - return ( -
- - Reload - - } - footer={!loading && renderFooter()} - loading={loading} - bordered - dataSource={data} - renderItem={item => ( - - - } - title={{item.title}} - description="umijs/hooks is a react hooks library" - /> - - )} - /> -
- ); -}; diff --git a/packages/hooks/src/useLoadMore/demo/demo5.tsx b/packages/hooks/src/useLoadMore/demo/demo5.tsx deleted file mode 100644 index e803dc0b4e..0000000000 --- a/packages/hooks/src/useLoadMore/demo/demo5.tsx +++ /dev/null @@ -1,133 +0,0 @@ -/** - * title: custom data loading - ID mode - * desc: If the data update frequency is very high, there may be multiple data corresponding to the same timestamp, and the timestamp mode above may have problems. At this point we can get the correct data by the id and offset of the last data. - * - * If there is an itemKey field in options, we will send the id of the current last data to asyncFn. - * - * title.zh-CN: 动态数据加载之 ID 模式 - * desc.zh-CN: 如果数据更新频率很高,可能同一个时间戳会对应多条数据,那上面的时间戳模式可能出现问题。这时候我们可以通过最后一条数据的 id 和 offset 来获取到正确的数据。 - * - * 如果 options 中有 itemKey 字段,我们会把当前最后一条数据的 id 发给 asyncFn。 - */ - -import { List, Button, Avatar } from 'antd'; -import React from 'react'; -import { useLoadMore } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/useLoadMore'; - -interface Item { - id: number; - title: string; -} -interface Result { - total: number; - data: Item[]; -} - -const dataSource = [ - { - id: 1, - title: 'Ant Design Title 1', - }, - { - id: 2, - title: 'Ant Design Title 2', - }, - { - id: 3, - title: 'Ant Design Title 3', - }, - { - id: 4, - title: 'Ant Design Title 4', - }, - { - id: 5, - title: 'Ant Design Title 5', - }, - { - id: 6, - title: 'Ant Design Title 6', - }, - { - id: 7, - title: 'Ant Design Title 7', - }, - { - id: 8, - title: 'Ant Design Title 8', - }, - { - id: 9, - title: 'Ant Design Title 9', - }, - { - id: 10, - title: 'Ant Design Title 10', - }, -]; - -const asyncFn = ({ pageSize, id = 0 }: FnParams): Promise => { - /* should query data by id */ - const filteredData = dataSource.filter(i => i.id > id); - return new Promise(resolve => { - setTimeout(() => { - resolve({ - total: dataSource.length, - data: filteredData.slice(0, pageSize), - }); - }, 1000); - }); -}; - -export default () => { - const { data, loading, loadingMore, reload, loadMore, total, noMore } = useLoadMore( - asyncFn, - { - initPageSize: 3, - incrementSize: 4, - itemKey: 'id', - }, - ); - - const renderFooter = () => ( - <> - {!noMore && ( - - )} - - {noMore && No more data} - - total: {total} - - ); - - return ( -
- - Reload - - } - footer={!loading && renderFooter()} - loading={loading} - bordered - dataSource={data} - renderItem={item => ( - - - } - title={{item.title}} - description="umijs/hooks is a react hooks library" - /> - - )} - /> -
- ); -}; diff --git a/packages/hooks/src/useLoadMore/index.en-US.md b/packages/hooks/src/useLoadMore/index.en-US.md deleted file mode 100644 index 214c6aa82d..0000000000 --- a/packages/hooks/src/useLoadMore/index.en-US.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: useLoadMore -order: 900 -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /deprecated/use-load-more ---- - -# useLoadMore - - -⚠️WARNING: useLoadMore is deprecated and will be removed in the next major version. Please use useRequest loadMore mode instead. - - -A Hook that is designed to display paged data incrementally. - -**Core Characteristics** - -* Async request control(loading, request timing control, etc) -* Logics will be used in common loadMore scenarios -* Support custom data loading method - -## Examples - -### Click to load more - - - -### Pull up load more - - - -### Use deps properly - - - -### Custom data loading - timestamp mode - - - -### Custom data loading - ID mode - - - -## API - -```javascript -const result: ReturnValue = useLoadMore( - asyncFn: (params: FnParams) => Promise, - options?: Options, -); - -const result: ReturnValue = useLoadMore( - asyncFn: (params: FnParams) => Promise, - deps?: any[], - options?: Options, -); - -``` - -### Result - -| Property | Description | Type | Default | -|-------------|------------------------------------------|------------|-------------| -| loading | Whether it is loading for the first time | boolean | false | -| loadingMore | Whether to load more | boolean | false | -| data | Full list data | any[] | [] | -| reload | Reload function | () => void | -| | -| loadMore | Load more function | () => void | - | -| noMore | Is there no more data | boolean | false | -| total | Total amount of data | number \| undefined|- | - - -### Params - -| Property | Description | Type | Default | -|----------|-------------------------------------------------------------------|----------------------|---------| -| asyncFn | Async request function, params see FnParams | (FnParams)=> Promise | - | -| deps | Depends on the array, if the deps changes, it will trigger reload | any[] | [] | -| options | Optional configuration item, see Options | - | - | - - -### FnParams - -| Property | Description | Type | Default | -|-----------|----------------------------------------------------------------------------------------------------------------------------------------------|--------|---------| -| page | Request page number. In general, if your initPageSize is not equal to incrementSize, then page doesn't make sense to you, you can use offset | number | - | -| pageSize | The number of requested data, the first page is equal to initPageSize, the non-first page is equal to incrementSize | number | - | -| offset | Data offset, which is how many pieces of data are currently in existence | number | - | -| id | The id of the last piece of data will only exist if itemKey is set | string | - | -| startTime | Start timestamp, recorded on the first load or each reload | number | - | - - -### Options - -| Property | Description | Type | Default | -|---------------|-------------------------------------------------------------------------------------------------|------------------------------------------------------|---------| -| initPageSize | first pageSize | number | 10 | -| incrementSize | PageSize other than the first page, if not set, equals initPageSize | number | - | -| itemKey | Data id, can be a string or a function | `string | ((record: Item, index: number) => string)` | - | -| formatResult | Format asyncFn request result | `(x: Result) => ({ total: number, data: Item[]})` | - | -| ref | The container's ref, if it exists, automatically triggers loadMore when scrolling to the bottom | `RefObject` | - | -| threshold | Set the distance bottom threshold when pulling down autoload | number | 100 | diff --git a/packages/hooks/src/useLoadMore/index.ts b/packages/hooks/src/useLoadMore/index.ts deleted file mode 100644 index 15433696d7..0000000000 --- a/packages/hooks/src/useLoadMore/index.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { DependencyList, RefObject, useEffect, useState, useCallback, useRef } from 'react'; -import useUpdateEffect from '../useUpdateEffect'; -import useAsync from '../useAsync'; - -export interface ReturnValue { - loading: boolean; - loadingMore: boolean; - data: Item[]; - reload: () => void; - loadMore: () => void; - noMore: boolean; - total: number | undefined; -} - -export interface Options { - initPageSize?: number; - incrementSize?: number; - itemKey?: string | ((record: Item, index: number) => string); - formatResult?: ( - x: Result, - ) => { - total: number; - data: Item[]; - }; - ref?: RefObject; - threshold?: number; -} - -export interface FnParams { - page: number; - pageSize: number; - offset: number; - id?: any; - startTime: number; -} - -function useLoadMore( - fn: (params: FnParams) => Promise, - options?: Options, -): ReturnValue; -function useLoadMore( - fn: (params: FnParams) => Promise, - deps?: DependencyList, - options?: Options, -): ReturnValue; -function useLoadMore( - fn: (params: FnParams) => Promise, - deps?: DependencyList | Options, - options?: Options, -): ReturnValue { - const _deps: DependencyList = (Array.isArray(deps) ? deps : []) as DependencyList; - const _options: Options = (typeof deps === 'object' && !Array.isArray(deps) - ? deps - : options || {}) as Options; - - /* 初始化值 */ - const { itemKey, initPageSize = 10, formatResult, ref, threshold = 100 } = _options; - let { incrementSize } = _options; - - if (!incrementSize) { - incrementSize = initPageSize; - } - - const [page, setPage] = useState(1); - const [total, setTotal] = useState(); - const [data, setData] = useState([]); - - /* 控制重新执行 */ - const [count, setCount] = useState(0); - - /* 开始的时间戳 */ - const startTime = useRef(new Date().getTime()); - - const { run, loading } = useAsync(fn, [], { - manual: true, - }); - - /* id 模式下读取 Key */ - const getItemKey = useCallback( - (item: Item, index: number) => { - const key = - typeof itemKey === 'function' ? itemKey(item, index) : (item as any)[itemKey as any]; - return key === undefined ? index : key; - }, - [itemKey], - ); - - const loadData = useCallback(() => { - const params: FnParams = { - page, - pageSize: (page === 1 ? initPageSize : incrementSize) as number, - offset: data.length, - startTime: startTime.current, - }; - - /* id 模式需要增加最后一个 id */ - if (itemKey) { - params.id = data.length > 0 ? getItemKey(data[data.length - 1], data.length - 1) : undefined; - } - - run(params).then((result: Result | undefined) => { - if (!result) { - return; - } - const { total: currentTotal, data: currentData } = (formatResult - ? formatResult(result) - : result) as any; - setData(data.concat(currentData)); - setTotal(currentTotal); - }); - }, [page, initPageSize, incrementSize, data]); - - const loadMore = useCallback(() => { - if (total && data.length >= total) { - return; - } - setPage(page + 1); - setCount(count + 1); - }, [page, count, data, total]); - - const reload = useCallback(() => { - setPage(1); - setData([]); - startTime.current = new Date().getTime(); - setCount(count + 1); - }, [count]); - - /* 上拉加载的方法 */ - const scrollMethod = useCallback(() => { - if (loading || !ref || !ref.current) { - return; - } - if (ref.current.scrollHeight - ref.current.scrollTop <= ref.current.clientHeight + threshold) { - loadMore(); - } - }, [loading, ref, loadMore]); - - /* 如果有 ref,则会上拉加载更多 */ - useEffect(() => { - if (!ref || !ref.current) { - return () => {}; - } - ref.current.addEventListener('scroll', scrollMethod); - return () => { - if (ref && ref.current) { - ref.current.removeEventListener('scroll', scrollMethod); - } - }; - }, [scrollMethod]); - - /* 只有初始化,或者 count 变化时,才会执行 run */ - useEffect(() => { - loadData(); - }, [count]); - - /* deps 变化后,重新 reload */ - useUpdateEffect(() => { - reload(); - }, _deps); - - return { - data, - loading: loading && page === 1, - loadingMore: loading && page > 1, - reload, - loadMore, - total, - noMore: (!loading && !total) || (!!total && data.length >= total), - }; -} - -export default useLoadMore; diff --git a/packages/hooks/src/useLoadMore/index.zh-CN.md b/packages/hooks/src/useLoadMore/index.zh-CN.md deleted file mode 100644 index ebed9ed58a..0000000000 --- a/packages/hooks/src/useLoadMore/index.zh-CN.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: useLoadMore -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /zh-CN/deprecated/use-load-more ---- - -# useLoadMore - - -⚠️警告: useAsync 已经被废弃了,将在下一个大版本时移除,你可以使用 useRequest loadMore 模式 代替。 - - -一个适用于点击加载更多或上拉加载更多应用场景的 Hook。 - -**核心特性** - -* 异步请求控制(loading, 请求时序控制等) -* 封装了常见 loadMore 场景的逻辑 -* 支持动态数据 loadMore 场景 - -## 代码演示 - -### 点击加载更多 - - - -### 上拉加载更多 - - - -### 合理利用 deps - - - -### 动态数据加载之时间戳模式 - - - -### 动态数据加载之 ID 模式 - - - -## API - -```javascript -const result: ReturnValue = useLoadMore( - asyncFn: (params: FnParams) => Promise, - options?: Options, -); - -const result: ReturnValue = useLoadMore( - asyncFn: (params: FnParams) => Promise, - deps?: any[], - options?: Options, -); - -``` - -### Result - -| 参数 | 说明 | 类型 | 默认值 | -|-------------|--------------------|------------|-------------| -| loading | 是否第一次加载中 | boolean | false | -| loadingMore | 是否加载更多中 | boolean | false | -| data | 全部列表数据 | any[] | [] | -| reload | 重新加载函数 | () => void | - | -| loadMore | 加载更多函数 | () => void | - | -| noMore | 是否没有更多数据了 | boolean | false | -| total | 数据总量 | number \| undefined|- | - - -### 参数 - -| 参数 | 说明 | 类型 | 默认值 | -|---------|-----------------------------------------|--------------------|--------| -| asyncFn | 请求数据的函数,函数参数见 FnParams | (FnParams)=> Promise | - | -| deps | 依赖数组,如果 deps 变化,会触发 reload | any[] | [] | -| options | 可选配置项,见 Options | - | - | - - -### FnParams - -| 参数 | 说明 | 类型 | 默认值 | -|-----------|---------------------------------------------------------------------------------------------------------------|--------|--------| -| page | 请求第几页数据,一般来说,如果你的 initPageSize 不等于 incrementSize,那 page 对你没有意义,你可以使用 offset | number | - | -| pageSize | 请求数据数量,第一页等于 initPageSize,非第一页等于 incrementSize | number | - | -| offset | 数据偏移量,也就是当前已经存在多少条数据了 | number | - | -| id | 最后一条数据的 id,只有设置了 itemKey 后才会存在 | string | - | -| startTime | 开始时间戳,第一次加载或每次 reload 时记录 | number | - | - - -### Options - -| 参数 | 说明 | 类型 | 默认值 | -|---------------|-----------------------------------------------------------|------------------------------------------------------|--------| -| initPageSize | 第一页的 pageSize | number | 10 | -| incrementSize | 非第一页的 pageSize,如果不设置,则等于 initPageSize | number | - | -| itemKey | 数据 id,可以是字符串或一个函数 | `string | ((record: Item, index: number) => string)` | - | -| formatResult | 格式化 service 请求结果 | `(x: Result) => ({ total: number, data: Item[]})` | - | -| ref | 容器的 ref,如果存在,则在滚动到底部时,自动触发 loadMore | `RefObject` | - | -| threshold | 下拉自动加载,距离底部距离阈值 | number | 100 | diff --git a/packages/hooks/src/useLocalStorageState/demo/demo1.tsx b/packages/hooks/src/useLocalStorageState/demo/demo1.tsx index aee57309ef..78ef82e670 100644 --- a/packages/hooks/src/useLocalStorageState/demo/demo1.tsx +++ b/packages/hooks/src/useLocalStorageState/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Input, Button } from 'antd'; -import { useLocalStorageState } from '@umijs/hooks'; +import { useLocalStorageState } from 'ahooks'; export default function () { const [message, setMessage] = useLocalStorageState('user-message', 'Hello~'); diff --git a/packages/hooks/src/useLocalStorageState/demo/demo2.tsx b/packages/hooks/src/useLocalStorageState/demo/demo2.tsx index 2fad726e6f..77b0c123d7 100644 --- a/packages/hooks/src/useLocalStorageState/demo/demo2.tsx +++ b/packages/hooks/src/useLocalStorageState/demo/demo2.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Cascader } from 'antd'; -import { useLocalStorageState } from '@umijs/hooks'; +import { useLocalStorageState } from 'ahooks'; const options = [ { diff --git a/packages/hooks/src/useLocalStorageState/demo/demo3.tsx b/packages/hooks/src/useLocalStorageState/demo/demo3.tsx index cad41ef54b..8b1bb0ea37 100644 --- a/packages/hooks/src/useLocalStorageState/demo/demo3.tsx +++ b/packages/hooks/src/useLocalStorageState/demo/demo3.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Input } from 'antd'; -import { useLocalStorageState } from '@umijs/hooks'; +import { useLocalStorageState } from 'ahooks'; interface IUser { id: number; diff --git a/packages/hooks/src/useMap/demo/demo1.tsx b/packages/hooks/src/useMap/demo/demo1.tsx index cf83fa1507..a99fa48300 100644 --- a/packages/hooks/src/useMap/demo/demo1.tsx +++ b/packages/hooks/src/useMap/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button } from 'antd'; -import { useMap } from '@umijs/hooks'; +import { useMap } from 'ahooks'; export default () => { const [map, { set, setAll, remove, reset, get }] = useMap([['msg', 'hello world'], [123, 'number type']]); diff --git a/packages/hooks/src/useMount/demo/demo1.tsx b/packages/hooks/src/useMount/demo/demo1.tsx index de0a831506..e1bd58edf3 100644 --- a/packages/hooks/src/useMount/demo/demo1.tsx +++ b/packages/hooks/src/useMount/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button, message } from 'antd'; -import { useToggle, useMount } from '@umijs/hooks'; +import { useToggle, useMount } from 'ahooks'; const MyComponent = () => { useMount( diff --git a/packages/hooks/src/useMouse/demo/demo1.tsx b/packages/hooks/src/useMouse/demo/demo1.tsx index d122117d5d..df15241feb 100644 --- a/packages/hooks/src/useMouse/demo/demo1.tsx +++ b/packages/hooks/src/useMouse/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React, { useMemo } from 'react'; -import {useMouse} from '@umijs/hooks'; +import {useMouse} from 'ahooks'; export default () => { const mouse = useMouse(); diff --git a/packages/hooks/src/usePagination/__tests__/index.test.ts b/packages/hooks/src/usePagination/__tests__/index.test.ts deleted file mode 100644 index d7da8491a9..0000000000 --- a/packages/hooks/src/usePagination/__tests__/index.test.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks'; -import { DependencyList } from 'react'; -import usePagination, { Options, ReturnValue, FnParams } from '../index'; - -/* 暂时关闭 act 警告 见:https://github.com/testing-library/react-testing-library/issues/281#issuecomment-480349256 */ -const originalError = console.error; -beforeAll(() => { - console.error = (...args: any) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return; - } - originalError.call(console, ...args); - }; -}); -afterAll(() => { - console.error = originalError; -}); - -interface Params { - asyncFn: (params: FnParams) => Promise; - deps?: DependencyList; - options?: Options; -} - -describe('usePagination', () => { - let queryArgs: any; - const asyncFn = (query: FnParams) => { - queryArgs = query; - return Promise.resolve({ - current: query.current, - total: 20, - pageSize: query.pageSize, - data: [], - }); - }; - - const setUp = ({ asyncFn: fn, deps, options }: Params) => - renderHook(params => usePagination(params.asyncFn, params.deps, params.options), { - initialProps: { - asyncFn: fn, - deps, - options, - } as Params, - }); - - let hook: RenderHookResult>; - - it('should be defined', () => { - expect(usePagination).toBeDefined(); - }); - - it('should fetch after first render', async () => { - queryArgs = undefined; - act(() => { - hook = setUp({ - asyncFn, - }); - }); - - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(10); - await hook.waitForNextUpdate(); - expect(hook.result.current.loading).toEqual(false); - expect(hook.result.current.pagination.current).toEqual(1); - expect(hook.result.current.pagination.pageSize).toEqual(10); - expect(hook.result.current.pagination.total).toEqual(20); - }); - - it('should options work', async () => { - queryArgs = undefined; - act(() => { - hook = setUp({ - asyncFn, - options: { - defaultPageSize: 5, - formatResult: (res: any) => ({ - ...res, - total: 22, - }), - }, - }); - }); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(5); - await hook.waitForNextUpdate(); - expect(hook.result.current.pagination.pageSize).toEqual(5); - expect(hook.result.current.pagination.total).toEqual(22); - }); - - it('should actions work', async () => { - queryArgs = undefined; - act(() => { - hook = setUp({ - asyncFn, - }); - }); - await hook.waitForNextUpdate(); - expect(hook.result.current.pagination.current).toEqual(1); - expect(hook.result.current.pagination.pageSize).toEqual(10); - expect(hook.result.current.pagination.totalPage).toEqual(2); - /* should changeCurrent work */ - act(() => { - hook.result.current.pagination.changeCurrent(3); - }); - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(2); - expect(queryArgs.pageSize).toEqual(10); - await hook.waitForNextUpdate(); - expect(hook.result.current.pagination.current).toEqual(2); - /* should changePageSize work */ - act(() => { - hook.result.current.pagination.changePageSize(5); - }); - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(2); - expect(queryArgs.pageSize).toEqual(5); - await hook.waitForNextUpdate(); - expect(hook.result.current.pagination.pageSize).toEqual(5); - /* should onChange work */ - act(() => { - hook.result.current.pagination.onChange(10, 50); - }); - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(50); - await hook.waitForNextUpdate(); - expect(hook.result.current.pagination.current).toEqual(1); - expect(hook.result.current.pagination.pageSize).toEqual(50); - /* should onChange work when current and pageSize error */ - act(() => { - hook.result.current.pagination.onChange(-1, -1); - }); - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(1); - await hook.waitForNextUpdate(); - expect(hook.result.current.pagination.current).toEqual(1); - expect(hook.result.current.pagination.pageSize).toEqual(1); - expect(hook.result.current.pagination.totalPage).toEqual(20); - /* should refresh work */ - act(() => { - hook.result.current.refresh(); - }); - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(1); - }); - - it('should refresh after deps change', async () => { - queryArgs = undefined; - - act(() => { - hook = setUp({ - asyncFn, - deps: [1], - }); - }); - - expect(hook.result.current.loading).toEqual(true); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(10); - await hook.waitForNextUpdate(); - expect(hook.result.current.loading).toEqual(false); - act(() => { - hook.result.current.pagination.onChange(2, 5); - }); - await hook.waitForNextUpdate(); - expect(hook.result.current.loading).toEqual(false); - expect(hook.result.current.pagination.current).toEqual(2); - expect(hook.result.current.pagination.pageSize).toEqual(5); - - act(() => { - hook.rerender({ - asyncFn, - deps: [2], - }); - }); - expect(queryArgs.current).toEqual(1); - expect(queryArgs.pageSize).toEqual(5); - }); -}); diff --git a/packages/hooks/src/usePagination/demo/demo1.tsx b/packages/hooks/src/usePagination/demo/demo1.tsx deleted file mode 100644 index bebc64f398..0000000000 --- a/packages/hooks/src/usePagination/demo/demo1.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/** - * title: Default usage - * desc: Simple paged list. - * - * title.zh-CN: 基本用法 - * desc.zh-CN: 简单的分页列表。 - */ - -import { usePagination } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/usePagination'; -import { Avatar, Card, List } from 'antd'; -import { PaginationConfig } from 'antd/lib/pagination'; -import React from 'react'; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -const queryData = ({ current, pageSize }: FnParams) => - fetch(`https://randomuser.me/api?results=${pageSize}&page=${current}`) - .then(res => res.json()) - .then(res => ({ - total: 55, - data: res.results, - })); - -export default () => { - const { data, loading, pagination } = usePagination(queryData, { - defaultPageSize: 9, - }); - return ( - ( - - - - } - title={item.name.last} - description="umi hooks is a react hooks library" - /> - - - )} - /> - ); -}; diff --git a/packages/hooks/src/usePagination/demo/demo2.tsx b/packages/hooks/src/usePagination/demo/demo2.tsx deleted file mode 100644 index 608e928ad6..0000000000 --- a/packages/hooks/src/usePagination/demo/demo2.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/** - * title: Using deps properly - * desc: When deps changes, the page number will be reset. - * - * title.zh-CN: 合理利用 deps - * desc.zh-CN: 当 deps 变化时,会初始化到第一页。 - */ - -import { List, Pagination, Select } from 'antd'; -import { PaginationConfig } from 'antd/lib/pagination'; -import React, { useState } from 'react'; -import { usePagination } from '@umijs/hooks'; -import { FnParams } from '@umijs/hooks/es/usePagination'; - -interface Item { - name: { - last: string; - }; - email: string; - phone: string; - gender: 'male' | 'female'; -} - -interface Result { - total: number; - data: Item[]; -} - -const queryData = ({ current, pageSize, gender }: FnParams) => - fetch(`https://randomuser.me/api?results=${pageSize}&page=${current}&gender=${gender}`) - .then(res => res.json()) - .then(res => ({ - total: 55, - data: res.results, - })); - -export default () => { - const [gender, setGender] = useState(); - const { data, loading, pagination } = usePagination( - params => queryData({ ...params, gender }), - [gender], - ); - return ( - <> - - ( - - {item.name.last} - {item.email} - - )} - /> - - - ); -}; diff --git a/packages/hooks/src/usePagination/index.en-US.md b/packages/hooks/src/usePagination/index.en-US.md deleted file mode 100644 index 64ee181017..0000000000 --- a/packages/hooks/src/usePagination/index.en-US.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: usePagination -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /deprecated/use-pagination ---- - -# usePagination - - -⚠️WARNING: usePagination is deprecated and will be removed in the next major version. Please use useRequest pagination mode instead. - - -Hook for common asynchronous paging scenario. - -## Examples - -### Default usage - - - -### Using deps properly - - - -## API - -```javascript -const result: ReturnValue = usePagination( - asyncFn: ({current, pageSize}) => Promise, - options?: Options, -); - -const result: ReturnValue = usePagination( - asyncFn: ({current, pageSize}) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -| Property | Description | Type | -|---------------------------|----------------------------------|-------------------------------------------| -| data | Data list | Item[] | -| loading | Whether the data is loading | boolean | -| pagination.current | Current page number | number | -| pagination.pageSize | Current page size | number | -| pagination.total | Total amount of data | number | -| pagination.totalPage | Total pages | number | -| pagination.onChange | Modify both current and pageSize | (current: number, pageSize: number)=>void | -| pagination.changeCurrent | Change current | (current: number)=>void | -| pagination.changePageSize | Change pageSize | (pageSize: number)=>void | -| refresh | Refresh data | () => void | - -### Params - -| Property | Description | Type | Default | -|----------|----------------------------------------------------------------------------------|--------------------------------|---------| -| asyncFn | Asynchronous request data function, function parameters are current and pageSize | ({current, pageSize})=>Promise | - | -| deps | Depends array, if deps change, it will reset current and trigger asyncFn | any[] | [] | -| options | Optional configuration items, see Options | - | - | - - -### Options - -| Property | Description | Type | Default | -|-----------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------|---------| -| defaultPageSize | default page size | number | 10 | -| formatResult | Format the asyncFn return data. If the asyncFn return data meets the requirements, then this parameter is not needed. | (res: Result)=>({total, data}) | - | diff --git a/packages/hooks/src/usePagination/index.ts b/packages/hooks/src/usePagination/index.ts deleted file mode 100644 index 3c9deec0dd..0000000000 --- a/packages/hooks/src/usePagination/index.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { useState, useEffect, useCallback, DependencyList, useMemo } from 'react'; -import useAsync from '../useAsync'; -import useUpdateEffect from '../useUpdateEffect'; - -export interface ReturnValue { - data: Item[]; - loading: boolean; - pagination: { - current: number; - pageSize: number; - total: number; - totalPage: number; - onChange: (current: number, pageSize: number) => void; - changeCurrent: (current: number) => void; - changePageSize: (pageSize: number) => void; - }; - refresh: () => void; -} - -export interface FormattedResult { - current?: number; - pageSize?: number; - total: number; - data: Item[]; -} - -export interface Options { - defaultPageSize?: number; - formatResult?: (result: Result) => FormattedResult; -} - -export interface FnParams { - current: number; - pageSize: number; - [key: string]: any; -} - -function usePagination( - fn: (params: FnParams) => Promise, - options?: Options, -): ReturnValue; -function usePagination( - fn: (params: FnParams) => Promise, - deps?: DependencyList, - options?: Options, -): ReturnValue; -function usePagination( - fn: (params: FnParams) => Promise, - deps?: DependencyList | Options, - options?: Options, -): ReturnValue { - const _deps: DependencyList = (Array.isArray(deps) ? deps : []) as DependencyList; - const _options: Options = (typeof deps === 'object' && !Array.isArray(deps) - ? deps - : options || {}) as Options; - const { defaultPageSize = 10, formatResult } = _options; - - const [data, setData] = useState([]); - const [total, setTotal] = useState(0); - const [current, setCurrent] = useState(1); - const [pageSize, setPageSize] = useState(defaultPageSize); - const [count, setCount] = useState(0); - - // let shamFn!: (params: FnParams) => Promise>; - - // if (Array.isArray(fn)) { - // shamFn = (params) => { - // return new Promise((resolve) => { - // resolve({ - // data: fn.slice((params.current - 1) * params.pageSize, params.current * params.pageSize), - // total: fn.length - // }); - // }); - // } - // } - - const { run, loading } = useAsync(fn, _deps, { - manual: true, - }); - - useEffect(() => { - run({ - current, - pageSize, - }).then(res => { - if (!res) { - return; - } - const formattedResult = formatResult - ? formatResult(res) - : ((res as unknown) as FormattedResult); - if (formattedResult) { - if (typeof formattedResult.total === 'number') setTotal(formattedResult.total); - if (formattedResult.data) setData(formattedResult.data); - if (typeof formattedResult.current === 'number') setCurrent(formattedResult.current); - if (typeof formattedResult.pageSize === 'number') setPageSize(formattedResult.pageSize); - } - }); - }, [current, pageSize, count]); - - useUpdateEffect(() => { - setCurrent(1); - setCount(c => c + 1); - }, _deps); - - const totalPage = useMemo(() => Math.ceil(total / pageSize), [pageSize, total]); - - const onChange = useCallback( - (c: number, p: number) => { - let toCurrent = c <= 0 ? 1 : c; - const toPageSize = p <= 0 ? 1 : p; - - const tempTotalPage = Math.ceil(total / toPageSize); - if (toCurrent > tempTotalPage) { - toCurrent = tempTotalPage; - } - setCurrent(toCurrent); - setPageSize(toPageSize); - }, - [total], - ); - - const changeCurrent = useCallback( - (c: number) => { - onChange(c, pageSize); - }, - [onChange, pageSize], - ); - - const changePageSize = useCallback( - (p: number) => { - onChange(current, p); - }, - [onChange, current], - ); - - const refresh = useCallback(() => { - setCount(c => c + 1); - }, []); - - return { - data, - loading, - - pagination: { - current, - pageSize, - total, - totalPage, - onChange, - changeCurrent, - changePageSize, - }, - refresh, - }; -} - -export default usePagination; diff --git a/packages/hooks/src/usePagination/index.zh-CN.md b/packages/hooks/src/usePagination/index.zh-CN.md deleted file mode 100644 index 5adac8fcf9..0000000000 --- a/packages/hooks/src/usePagination/index.zh-CN.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: usePagination -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /zh-CN/deprecated/use-pagination ---- - -# usePagination - - -⚠️警告: usePagination 已经被废弃了,将在下一个大版本时移除,你可以使用 useRequest 分页模式 代替。 - - -适用于常见的异步分页场景的 Hook。 - -## 代码演示 - -### 基本用法 - - - -### 合理利用 deps - - - -## API - -```javascript -const result: ReturnValue = usePagination( - asyncFn: ({current, pageSize}) => Promise, - options?: Options, -); - -const result: ReturnValue = usePagination( - asyncFn: ({current, pageSize}) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -| 参数 | 说明 | 类型 | -|---------------------------|------------------------------|-------------------------------------------| -| data | 数据 | Item[] | -| loading | 数据是否正在加载 | boolean | -| pagination.current | 当前页号 | number | -| pagination.pageSize | 每页数据量 | number | -| pagination.total | 数据总量 | number | -| pagination.totalPage | 总页数 | number | -| pagination.onChange | 同时修改 current 和 pageSize | (current: number, pageSize: number)=>void | -| pagination.changeCurrent | 单独修改 current | (current: number)=>void | -| pagination.changePageSize | 单独修改 pageSize | (pageSize: number)=>void | -| refresh | 刷新当前数据 | () => void | - -### Params - -| 参数 | 说明 | 类型 | 默认值 | -|---------|---------------------------------------------------------|--------------------------------|--------| -| asyncFn | 异步请求数据函数,函数参数为 current 和 pageSize | ({current, pageSize})=>Promise | - | -| deps | 依赖数组,如果 deps 变化,会重置 current 并触发 asyncFn | any[] | [] | -| options | 可选配置项,见 Options | - | - | - - -### Options - -| 参数 | 说明 | 类型 | 默认值 | -|-----------------|------------------------------------------------------------------------------|--------------------------------|--------| -| defaultPageSize | 默认的每页数据量 | number | 10 | -| formatResult | 对 asyncFn 返回数据进行格式化,如果 asyncFn 返回数据符合要求,则不需要该参数 | (res: Result)=>({total, data}) | - | diff --git a/packages/hooks/src/usePersistFn/demo/demo1.tsx b/packages/hooks/src/usePersistFn/demo/demo1.tsx index 14059fef1a..66692eabd2 100644 --- a/packages/hooks/src/usePersistFn/demo/demo1.tsx +++ b/packages/hooks/src/usePersistFn/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState, useCallback, useRef } from 'react'; import { Button, message } from 'antd'; -import { usePersistFn } from '@umijs/hooks'; +import { usePersistFn } from 'ahooks'; export default () => { const [count, setCount] = useState(0); diff --git a/packages/hooks/src/usePrevious/demo/demo1.tsx b/packages/hooks/src/usePrevious/demo/demo1.tsx index 7c4fe6a614..b9078c91d7 100644 --- a/packages/hooks/src/usePrevious/demo/demo1.tsx +++ b/packages/hooks/src/usePrevious/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; -import { usePrevious } from '@umijs/hooks'; +import { usePrevious } from 'ahooks'; export default () => { const [count, setCount] = useState(0); diff --git a/packages/hooks/src/usePrevious/demo/demo2.tsx b/packages/hooks/src/usePrevious/demo/demo2.tsx index 82af8181e7..4b74ae88e9 100644 --- a/packages/hooks/src/usePrevious/demo/demo2.tsx +++ b/packages/hooks/src/usePrevious/demo/demo2.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button, Input } from 'antd'; -import { usePrevious } from '@umijs/hooks'; +import { usePrevious } from 'ahooks'; interface Person { name: string; diff --git a/packages/hooks/src/useResponsive/demo/demo1.tsx b/packages/hooks/src/useResponsive/demo/demo1.tsx index 162099cb7d..ffe27375a0 100644 --- a/packages/hooks/src/useResponsive/demo/demo1.tsx +++ b/packages/hooks/src/useResponsive/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; -import { configResponsive, useResponsive } from '@umijs/hooks'; +import { configResponsive, useResponsive } from 'ahooks'; configResponsive({ small: 0, diff --git a/packages/hooks/src/useScroll/demo/demo1.tsx b/packages/hooks/src/useScroll/demo/demo1.tsx index e96636aa04..ecc45ddd79 100644 --- a/packages/hooks/src/useScroll/demo/demo1.tsx +++ b/packages/hooks/src/useScroll/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React, { useRef } from 'react'; -import {useScroll} from '@umijs/hooks'; +import {useScroll} from 'ahooks'; export default () => { const [scroll, ref] = useScroll(); diff --git a/packages/hooks/src/useScroll/demo/demo2.tsx b/packages/hooks/src/useScroll/demo/demo2.tsx index e814ce74a5..5294908bcd 100644 --- a/packages/hooks/src/useScroll/demo/demo2.tsx +++ b/packages/hooks/src/useScroll/demo/demo2.tsx @@ -7,7 +7,7 @@ */ import React, { useRef } from 'react'; -import {useScroll} from '@umijs/hooks'; +import {useScroll} from 'ahooks'; export default () => { const [scroll] = useScroll(document); diff --git a/packages/hooks/src/useSearch/__tests__/index.test.ts b/packages/hooks/src/useSearch/__tests__/index.test.ts deleted file mode 100644 index 93e05ba3e3..0000000000 --- a/packages/hooks/src/useSearch/__tests__/index.test.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { renderHook, act } from '@testing-library/react-hooks'; -import useSearch from '../index'; - -/* 暂时关闭 act 警告 见:https://github.com/testing-library/react-testing-library/issues/281#issuecomment-480349256 */ -const originalError = console.error; -beforeAll(() => { - console.error = (...args: any) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return; - } - originalError.call(console, ...args); - }; -}); - -afterAll(() => { - console.error = originalError; -}); - -const data = [1, 2, 3, 4, 5]; - -const asyncFn = (value: any) => new Promise(resolve => { - setTimeout(() => { - resolve(data.filter(item => item === value)); - }, 1); - }) - -const callChange = (hook: any, value: any) => { - act(() => { - const { onChange } = hook.result.current; - onChange(value); - }); -}; - -const callRun = (hook: any) => { - act(() => { - const { run } = hook.result.current; - run(); - }); -}; - -const callCancel = (hook: any) => { - act(() => { - const { cancel } = hook.result.current; - cancel(); - }); -}; - -describe('useSearch', () => { - it('should be defined', () => { - expect(useSearch).toBeDefined(); - }); - - // describe('should method run', () => { - // let hook: any; - // beforeEach(() => { - // hook = renderHook(({ fn, deps, options }) => useSearch(fn, deps, options), { - // initialProps: { fn: asyncFn, deps: undefined, options: {} }, - // }); - // }); - - // it('test on change', async () => { - // expect.assertions(4); - - // callChange(hook, 1); - // callChange(hook, 2); - // callChange(hook, 3); - // await hook.waitForNextUpdate(); - // expect(hook.result.current.loading).toBeTruthy(); - // await hook.waitForNextUpdate(); - // expect(hook.result.current.data).toBeDefined(); - // expect((hook.result.current.data as any)[0]).toEqual(3); - // expect(hook.result.current.loading).toBeFalsy(); - // }); - - // it('test on run', async () => { - // expect.assertions(2); - - // callChange(hook, 1); - // callRun(hook); - // await hook.waitForNextUpdate(); - // expect((hook.result.current.data as any)[0]).toEqual(1); - // callChange(hook, 2); - // callRun(hook); - // await hook.waitForNextUpdate(); - // expect((hook.result.current.data as any)[0]).toEqual(2); - // }); - - // it('test on cancel', async () => { - // expect.assertions(5); - - // callChange(hook, 1); - // await hook.waitForNextUpdate() - // expect(hook.result.current.loading).toBeTruthy(); - // expect(hook.result.current.value).toEqual(1); - // await hook.waitForNextUpdate(); - // callChange(hook, 2); - // callCancel(hook); - // expect(hook.result.current.loading).toBeFalsy(); - // expect((hook.result.current.data as any)[0]).toEqual(1); - // expect(hook.result.current.value).toEqual(2); - // }); - - // }); - - // describe('test on options', () => { - // let hook: any; - // beforeEach(() => { - // hook = renderHook(({ fn, deps, options }) => useSearch(fn, [deps], options), { - // initialProps: { - // fn: asyncFn, - // deps: null, - // options: undefined - // }, - // }); - // }); - - // it('should cancel in rerender return undefined', async () => { - // expect.assertions(2); - - // hook.rerender({ - // fn: asyncFn, - // options: { wait: 300 } - // }); - // callCancel(hook); - // expect(hook.result.current.loading).toBeFalsy(); - // expect(hook.result.current.data).toBeUndefined(); - // }); - // }); -}); diff --git a/packages/hooks/src/useSearch/demo/demo1.tsx b/packages/hooks/src/useSearch/demo/demo1.tsx deleted file mode 100644 index 5960c7e952..0000000000 --- a/packages/hooks/src/useSearch/demo/demo1.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/** - * title: Select Search - * desc: Common Select with asynchronous search. - * - * title.zh-CN: Select Search - * desc.zh-CN: 常见的 Select 异步搜索。 - */ - -import React from 'react'; -import { Select } from 'antd'; -import { useSearch } from '@umijs/hooks'; - -const { Option } = Select; - -const getEmail = (str: string) => { - console.log('search string: ', str); - return fetch(`https://randomuser.me/api/?results=5&email=${str}`) - .then(res => res.json()) - .then(res => res.results); -}; - -export default () => { - const { data, loading, onChange, cancel } = useSearch(getEmail); - - return ( - - ); -}; diff --git a/packages/hooks/src/useSearch/demo/demo2.tsx b/packages/hooks/src/useSearch/demo/demo2.tsx deleted file mode 100644 index 38fb7bd789..0000000000 --- a/packages/hooks/src/useSearch/demo/demo2.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/** - * title: Input Search - * desc: Complex Input search scenario, use deps properly. - * - * title.zh-CN: Input Search - * desc.zh-CN: 复杂的 Input 搜索场景,合理使用 deps。 - */ - -import React, { useState } from 'react'; -import { Select, Input, AutoComplete } from 'antd'; -import { useSearch } from '@umijs/hooks'; - -const { Option } = Select; - -const queryData = (type: string, text: string): Promise => { - console.log(type, text); - const data: string[] = []; - for (let i = 0; i < 10; i++) { - data.push(`${type}-${i}-${text}-${Math.round(Math.random() * 100)}`); - } - return new Promise(resolve => { - setTimeout(() => { - resolve(data); - }, 1000); - }); -}; - -export default () => { - const [type, setType] = useState('app'); - const { data = [], loading, onChange } = useSearch( - text => { - if (!text) { - return Promise.resolve([]); - } - return queryData(type, text); - }, - [type], - ); - - return ( - - - - - - - ); -}; diff --git a/packages/hooks/src/useSearch/index.en-US.md b/packages/hooks/src/useSearch/index.en-US.md deleted file mode 100644 index 8c5f37f627..0000000000 --- a/packages/hooks/src/useSearch/index.en-US.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: useSearch -nav: - title: Hooks - path: /hooks -group: - title: Deprecated - path: /deprecated -legacy: /deprecated/use-search ---- - -# useSearch - - -⚠️WARNING: useSearch is deprecated and will be removed in the next major version. Please use useRequest debounceInterval instead. - - -Applicable to typing while searching scenario. - -**Core Characteristics** - -* Async request control(loading, request timing control, etc) -* Debouncing -* Auto cleanup when unmount - -## Examples - -### Select Search - - - - -### Input Search - - - -## API - -```javascript -const result: Result = useSearch( - asyncFn: (value: any) => Promise, - options?: Options, -); - -const result: Result = useSearch( - asyncFn: (value: any) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -| Property | Description | Type | -|----------|-----------------------------------------------------|----------------------| -| data | Search result data | any | -| loading | Loading status | boolean | -| onChange | Trigger asyncFn, the parameters are sent to asyncFn | (value: any) => void | -| value | onChange parameters | - | -| cancel | Cancel the ongoing request and debounce in the wait | () => void | -| run | Re-execute the asyncFn with the current value | () => void | - -### Params - -| Property | Description | Type | Default | -|----------|--------------------------------------------------------------------|------------------------|---------| -| asyncFn | Async request function, parameter is onChange's value | (value: any)=> Promise | - | -| deps | Depends on the array, if the deps changes, it will trigger asyncFn | | | -| any[] | [] | | | -| options | Optional configuration item, see Options | - | - | - - -### Options - -| Property | Description | Type | Default | -|----------|-------------------|--------|---------| -| wait | Debounce interval | number | 300 | diff --git a/packages/hooks/src/useSearch/index.ts b/packages/hooks/src/useSearch/index.ts deleted file mode 100644 index d7e9f26b26..0000000000 --- a/packages/hooks/src/useSearch/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { DependencyList, useCallback, useMemo, useState } from 'react'; -import useAsync from '../useAsync'; -import useDebounceFn from '../useDebounceFn'; -import useUpdateEffect from '../useUpdateEffect'; - - -export interface ReturnValue { - loading: boolean; - data?: T; - value: any; - onChange: (value: any) => void; - cancel: () => void; - run: () => void; -} - -export interface Options { - wait?: number; -} - -function useSearch( - fn: (value: any) => Promise, - options?: Options, -): ReturnValue; -function useSearch( - fn: (value: any) => Promise, - deps?: DependencyList, - options?: Options, -): ReturnValue; -function useSearch( - fn: (value: any) => Promise, - deps?: DependencyList | Options, - options?: Options, -): ReturnValue { - const _deps: DependencyList = (Array.isArray(deps) ? deps : []) as DependencyList; - const _options: Options = (typeof deps === 'object' && !Array.isArray(deps) - ? deps - : options || {}) as Options; - - const [value, setValue] = useState(''); - - const { loading, data, run, cancel: cancelAsync } = useAsync(fn, [value, ..._deps], { - manual: true, - }); - - const wait: number = useMemo(() => (_options.wait === undefined ? 300 : _options.wait), [ - _options.wait, - ]); - - const debounce = useDebounceFn( - () => { - run(value); - }, - [value], - wait, - ); - - /* 依赖变化时,需要立即重新请求 */ - useUpdateEffect(() => { - run(value); - }, _deps); - - const cancel = useCallback(() => { - /* 先取消防抖 */ - debounce.cancel(); - /* 再取消 async */ - cancelAsync(); - }, [cancelAsync, debounce.cancel]); - - /* 手动触发 */ - const trigger = useCallback(() => { - run(value); - }, [run, value]); - - return { - data, - loading, - value, - onChange: setValue, - cancel, - run: trigger, - }; -} - -export default useSearch; diff --git a/packages/hooks/src/useSearch/index.zh-CN.md b/packages/hooks/src/useSearch/index.zh-CN.md deleted file mode 100644 index 17db20c00a..0000000000 --- a/packages/hooks/src/useSearch/index.zh-CN.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: useSearch -nav: - title: Hooks - path: /hooks -group: - title: 废弃 - path: /deprecated -legacy: /zh-CN/deprecated/use-search ---- - -# useSearch - - -⚠️警告: useSearch 已经被废弃了,将在下一个大版本时移除,你可以使用 useRequest debounceInterval 代替。 - - -适用于常见的边输入,边异步搜索的场景。 - -**核心特性** - -* 异步请求控制(loading, 请求时序控制等) -* 防抖 -* 自动卸载 - -## 代码演示 - -### Select Search - - - - -### Input Search - - - - -## API - -```javascript -const result: Result = useSearch( - asyncFn: (value: any) => Promise, - options?: Options, -); - -const result: Result = useSearch( - asyncFn: (value: any) => Promise, - deps?: any[], - options?: Options, -); -``` - -### Result - -| 参数 | 说明 | 类型 | -|----------|--------------------------------------|----------------------| -| data | 搜索结果数据 | any | -| loading | 是否正在加载 | boolean | -| onChange | 触发搜索的函数,参数会发送给 asyncFn | (value: any) => void | -| value | onChange 的参数 | - | -| cancel | 取消进行中的请求和等待中的防抖 | () => void | -| run | 用当前 value 重新执行一次 asyncFn | () => void | - -### 参数 - -| 参数 | 说明 | 类型 | 默认值 | -|---------|------------------------------------------------|------------------------|--------| -| asyncFn | 异步请求数据函数,函数参数为 onChange 的 value | (value: any)=> Promise | - | -| deps | 依赖数组,如果 deps 变化,会触发 asyncFn | any[] | [] | -| options | 可选配置项,见 Options | - | - | - - -### Options - -| 参数 | 说明 | 类型 | 默认值 | -|------|--------------|--------|--------| -| wait | 防抖时间间隔 | number | 300 | diff --git a/packages/hooks/src/useSelections/demo/demo1.tsx b/packages/hooks/src/useSelections/demo/demo1.tsx index 26b9ab11be..6ecfc54c50 100644 --- a/packages/hooks/src/useSelections/demo/demo1.tsx +++ b/packages/hooks/src/useSelections/demo/demo1.tsx @@ -8,7 +8,7 @@ import { Checkbox, Col, Row } from 'antd'; import React, { useMemo, useState } from 'react'; -import { useSelections } from '@umijs/hooks' +import { useSelections } from 'ahooks' export default () => { const [hideOdd, setHideOdd] = useState(false); diff --git a/packages/hooks/src/useSessionStorageState/demo/demo1.tsx b/packages/hooks/src/useSessionStorageState/demo/demo1.tsx index b762bf4312..ddff54fc47 100644 --- a/packages/hooks/src/useSessionStorageState/demo/demo1.tsx +++ b/packages/hooks/src/useSessionStorageState/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Input, Button } from 'antd'; -import { useSessionStorageState } from '@umijs/hooks'; +import { useSessionStorageState } from 'ahooks'; export default function () { const [message, setMessage] = useSessionStorageState('user-message', 'Hello~'); diff --git a/packages/hooks/src/useSessionStorageState/demo/demo2.tsx b/packages/hooks/src/useSessionStorageState/demo/demo2.tsx index ef33b5f919..c588ce024d 100644 --- a/packages/hooks/src/useSessionStorageState/demo/demo2.tsx +++ b/packages/hooks/src/useSessionStorageState/demo/demo2.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Cascader } from 'antd'; -import { useSessionStorageState } from '@umijs/hooks'; +import { useSessionStorageState } from 'ahooks'; const options = [ { diff --git a/packages/hooks/src/useSessionStorageState/demo/demo3.tsx b/packages/hooks/src/useSessionStorageState/demo/demo3.tsx index f0319c0e54..879c85170d 100644 --- a/packages/hooks/src/useSessionStorageState/demo/demo3.tsx +++ b/packages/hooks/src/useSessionStorageState/demo/demo3.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Input } from 'antd'; -import { useSessionStorageState } from '@umijs/hooks'; +import { useSessionStorageState } from 'ahooks'; interface IUser { id: number; diff --git a/packages/hooks/src/useSet/demo/demo1.tsx b/packages/hooks/src/useSet/demo/demo1.tsx index 17a419234a..af55170e6d 100644 --- a/packages/hooks/src/useSet/demo/demo1.tsx +++ b/packages/hooks/src/useSet/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button } from 'antd'; -import { useSet } from '@umijs/hooks'; +import { useSet } from 'ahooks'; export default () => { const [set, { add, has, remove, reset }] = useSet(['Hello']); diff --git a/packages/hooks/src/useSize/demo/demo1.tsx b/packages/hooks/src/useSize/demo/demo1.tsx index 1ef4393df9..8eb38a2567 100644 --- a/packages/hooks/src/useSize/demo/demo1.tsx +++ b/packages/hooks/src/useSize/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import {useSize} from '@umijs/hooks'; +import {useSize} from 'ahooks'; export default () => { const [state, ref] = useSize(); diff --git a/packages/hooks/src/useSize/demo/demo2.tsx b/packages/hooks/src/useSize/demo/demo2.tsx index 6eb195da8d..63cb0b2c2e 100644 --- a/packages/hooks/src/useSize/demo/demo2.tsx +++ b/packages/hooks/src/useSize/demo/demo2.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import {useSize} from '@umijs/hooks'; +import {useSize} from 'ahooks'; export default () => { const [state] = useSize(() => document.querySelector('#demo2')); diff --git a/packages/hooks/src/useSize/demo/demo3.tsx b/packages/hooks/src/useSize/demo/demo3.tsx index 7b8e078be9..e10d759324 100644 --- a/packages/hooks/src/useSize/demo/demo3.tsx +++ b/packages/hooks/src/useSize/demo/demo3.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import {useSize} from '@umijs/hooks'; +import {useSize} from 'ahooks'; export default () => { const [state] = useSize(document.querySelector('body')); diff --git a/packages/hooks/src/useTextSelection/demo/demo1.tsx b/packages/hooks/src/useTextSelection/demo/demo1.tsx index f025142d28..0d3aed900f 100644 --- a/packages/hooks/src/useTextSelection/demo/demo1.tsx +++ b/packages/hooks/src/useTextSelection/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import { useTextSelection } from '@umijs/hooks'; +import { useTextSelection } from 'ahooks'; export default () => { const [selection] = useTextSelection(document); diff --git a/packages/hooks/src/useTextSelection/demo/demo2.tsx b/packages/hooks/src/useTextSelection/demo/demo2.tsx index 0a4515f626..b887080dfe 100644 --- a/packages/hooks/src/useTextSelection/demo/demo2.tsx +++ b/packages/hooks/src/useTextSelection/demo/demo2.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import { useTextSelection } from '@umijs/hooks'; +import { useTextSelection } from 'ahooks'; export default () => { const [{ diff --git a/packages/hooks/src/useTextSelection/demo/demo3.tsx b/packages/hooks/src/useTextSelection/demo/demo3.tsx index e7c2e7374d..4c5a143726 100644 --- a/packages/hooks/src/useTextSelection/demo/demo3.tsx +++ b/packages/hooks/src/useTextSelection/demo/demo3.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 配合 Popover 做划词翻译 */ -import { useRequest, useTextSelection } from '@umijs/hooks'; +import { useRequest, useTextSelection } from 'ahooks'; import { Popover, Spin } from 'antd'; import React, { useEffect, useState } from 'react'; diff --git a/packages/hooks/src/useTextSelection/demo/demo4.tsx b/packages/hooks/src/useTextSelection/demo/demo4.tsx index 3d4de34718..c54cfef997 100644 --- a/packages/hooks/src/useTextSelection/demo/demo4.tsx +++ b/packages/hooks/src/useTextSelection/demo/demo4.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import { useTextSelection } from '@umijs/hooks'; +import { useTextSelection } from 'ahooks'; export default () => { const [selection, ref] = useTextSelection(); diff --git a/packages/hooks/src/useThrottle/demo/demo1.tsx b/packages/hooks/src/useThrottle/demo/demo1.tsx index 757f7fe37a..23c8e7dba7 100644 --- a/packages/hooks/src/useThrottle/demo/demo1.tsx +++ b/packages/hooks/src/useThrottle/demo/demo1.tsx @@ -8,7 +8,7 @@ import { Input } from 'antd'; import React, { useState } from 'react'; -import { useThrottle } from '@umijs/hooks'; +import { useThrottle } from 'ahooks'; export default () => { const [value, setValue] = useState(); diff --git a/packages/hooks/src/useThrottleFn/demo/demo1.tsx b/packages/hooks/src/useThrottleFn/demo/demo1.tsx index 9d6d5571f2..80130af57d 100644 --- a/packages/hooks/src/useThrottleFn/demo/demo1.tsx +++ b/packages/hooks/src/useThrottleFn/demo/demo1.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; -import { useThrottleFn } from '@umijs/hooks'; +import { useThrottleFn } from 'ahooks'; export default () => { const [value, setValue] = useState(0); diff --git a/packages/hooks/src/useThrottleFn/demo/demo2.tsx b/packages/hooks/src/useThrottleFn/demo/demo2.tsx index d41e98ee45..5c03d230bc 100644 --- a/packages/hooks/src/useThrottleFn/demo/demo2.tsx +++ b/packages/hooks/src/useThrottleFn/demo/demo2.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { Button, Input } from 'antd'; -import { useThrottleFn } from '@umijs/hooks'; +import { useThrottleFn } from 'ahooks'; export default () => { const [value, setValue] = useState(); diff --git a/packages/hooks/src/useToggle/demo/demo1.tsx b/packages/hooks/src/useToggle/demo/demo1.tsx index 82466a5d62..59321e459b 100644 --- a/packages/hooks/src/useToggle/demo/demo1.tsx +++ b/packages/hooks/src/useToggle/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button, Switch } from 'antd'; -import { useToggle } from '@umijs/hooks'; +import { useToggle } from 'ahooks'; export default () => { const { state, toggle } = useToggle(); diff --git a/packages/hooks/src/useToggle/demo/demo2.tsx b/packages/hooks/src/useToggle/demo/demo2.tsx index 44729f7dff..c491a203c2 100644 --- a/packages/hooks/src/useToggle/demo/demo2.tsx +++ b/packages/hooks/src/useToggle/demo/demo2.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button } from 'antd'; -import { useToggle } from '@umijs/hooks'; +import { useToggle } from 'ahooks'; export default () => { const { state, toggle, setLeft, setRight } = useToggle('Hello', 'World'); diff --git a/packages/hooks/src/useUnmount/demo/demo1.tsx b/packages/hooks/src/useUnmount/demo/demo1.tsx index ddb577214a..454f16e717 100644 --- a/packages/hooks/src/useUnmount/demo/demo1.tsx +++ b/packages/hooks/src/useUnmount/demo/demo1.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Button, message } from 'antd'; -import { useUnmount, useToggle } from '@umijs/hooks'; +import { useUnmount, useToggle } from 'ahooks'; const MyComponent = () => { useUnmount( diff --git a/packages/hooks/src/useUpdate/demo/demo1.tsx b/packages/hooks/src/useUpdate/demo/demo1.tsx index 522dd7d20b..285b9b05a0 100644 --- a/packages/hooks/src/useUpdate/demo/demo1.tsx +++ b/packages/hooks/src/useUpdate/demo/demo1.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Button } from 'antd'; -import { useUpdate } from '@umijs/hooks'; +import { useUpdate } from 'ahooks'; export default () => { diff --git a/packages/hooks/src/useUpdateEffect/demo/demo1.tsx b/packages/hooks/src/useUpdateEffect/demo/demo1.tsx index 9f78ffbe18..25171b5c93 100644 --- a/packages/hooks/src/useUpdateEffect/demo/demo1.tsx +++ b/packages/hooks/src/useUpdateEffect/demo/demo1.tsx @@ -8,7 +8,7 @@ import { Button } from 'antd'; import React, { useLayoutEffect, useState } from 'react'; -import { useUpdateEffect } from '@umijs/hooks'; +import { useUpdateEffect } from 'ahooks'; export default () => { const [count, setCount] = useState(0); diff --git a/packages/hooks/src/useUpdateLayoutEffect/demo/demo1.tsx b/packages/hooks/src/useUpdateLayoutEffect/demo/demo1.tsx index 4ea984dbff..5ba27186b1 100644 --- a/packages/hooks/src/useUpdateLayoutEffect/demo/demo1.tsx +++ b/packages/hooks/src/useUpdateLayoutEffect/demo/demo1.tsx @@ -8,7 +8,7 @@ import { Button } from 'antd'; import React, { useLayoutEffect, useState } from 'react'; -import { useUpdateLayoutEffect } from '@umijs/hooks'; +import { useUpdateLayoutEffect } from 'ahooks'; export default () => { const [count, setCount] = useState(0); diff --git a/packages/hooks/src/useVirtualList/demo/demo1.tsx b/packages/hooks/src/useVirtualList/demo/demo1.tsx index a99fe77758..57b3e8eea4 100644 --- a/packages/hooks/src/useVirtualList/demo/demo1.tsx +++ b/packages/hooks/src/useVirtualList/demo/demo1.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; -import { useVirtualList } from '@umijs/hooks'; +import { useVirtualList } from 'ahooks'; export default () => { const { list, containerProps, wrapperProps } = useVirtualList(Array.from(Array(99999).keys()), { diff --git a/packages/hooks/src/useVirtualList/demo/demo2.tsx b/packages/hooks/src/useVirtualList/demo/demo2.tsx index af7a8bb080..8775361236 100644 --- a/packages/hooks/src/useVirtualList/demo/demo2.tsx +++ b/packages/hooks/src/useVirtualList/demo/demo2.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { InputNumber, Button } from 'antd'; -import { useVirtualList } from '@umijs/hooks'; +import { useVirtualList } from 'ahooks'; export default () => { const [value, onChange] = React.useState(undefined); diff --git a/packages/use-request/demo/axios.tsx b/packages/use-request/demo/axios.tsx index e6785f3385..da4764ab52 100644 --- a/packages/use-request/demo/axios.tsx +++ b/packages/use-request/demo/axios.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过设置 `requstMethod`, 可以使用自己的请求库。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import React from 'react'; import axios from 'axios'; diff --git a/packages/use-request/demo/cacheKey.tsx b/packages/use-request/demo/cacheKey.tsx index 9451d39056..3749df52f6 100644 --- a/packages/use-request/demo/cacheKey.tsx +++ b/packages/use-request/demo/cacheKey.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 如果设置了 `options.cacheKey` , useRequest 会将当前请求结束数据缓存起来。下次组件初始化时,如果有缓存数据,我们会优先返回缓存数据,然后在背后发送新请求,也就是 SWR 的能力。 */ -import { useBoolean, useRequest } from '@umijs/hooks'; +import { useBoolean, useRequest } from 'ahooks'; import { Button, Spin } from 'antd'; import Mock from 'mockjs'; import React from 'react'; diff --git a/packages/use-request/demo/concurrent.tsx b/packages/use-request/demo/concurrent.tsx index 71f3f3b06b..01fed25b80 100644 --- a/packages/use-request/demo/concurrent.tsx +++ b/packages/use-request/demo/concurrent.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过 `options.fetchKey` ,可以将请求进行分类,每一类的请求都有独立的状态,你可以在 `fetches` 中找到所有的请求。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Button, message } from 'antd'; import React from 'react'; diff --git a/packages/use-request/demo/debounce.tsx b/packages/use-request/demo/debounce.tsx index 0895695ed7..25da679013 100644 --- a/packages/use-request/demo/debounce.tsx +++ b/packages/use-request/demo/debounce.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过设置 `options.debounceInterval` ,则进入防抖模式。此时如果频繁触发 `run` ,则会以防抖策略进行请求。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Select } from 'antd'; import React from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/default.tsx b/packages/use-request/demo/default.tsx index 550437455a..2f5ea0399c 100644 --- a/packages/use-request/demo/default.tsx +++ b/packages/use-request/demo/default.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 在这个例子中, useRequest 接收了一个异步函数 `getUsername` ,在组件初次加载时, 自动触发该函数执行。同时 useRequest 会自动管理异步请求的 `loading` , `data` , `error` 等状态。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import Mock from 'mockjs'; import React from 'react'; diff --git a/packages/use-request/demo/loadMore-1.tsx b/packages/use-request/demo/loadMore-1.tsx index 962304cc4c..727857384a 100644 --- a/packages/use-request/demo/loadMore-1.tsx +++ b/packages/use-request/demo/loadMore-1.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过设置 cacheKey,可以缓存所有 list 数据。 */ -import { useBoolean, useRequest } from '@umijs/hooks'; +import { useBoolean, useRequest } from 'ahooks'; import { Button, Spin, List, Typography } from 'antd'; import React from 'react'; diff --git a/packages/use-request/demo/loadMore-2.tsx b/packages/use-request/demo/loadMore-2.tsx index c2f65ac128..3036fcdd7d 100644 --- a/packages/use-request/demo/loadMore-2.tsx +++ b/packages/use-request/demo/loadMore-2.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 如果 options 中存在 `ref`,则在滚动到底部时,自动触发 loadMore。当然此时你必须设置 `isNoMore`, 以便让 `useReqeust` 知道何时停止。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Avatar, Button, List } from 'antd'; import React, { useRef } from 'react'; @@ -119,7 +119,7 @@ export default () => { } title={{item.title}} - description="umijs/hooks is a react hooks library" + description="ahooks is a react hooks library" /> )} diff --git a/packages/use-request/demo/loadingDelay.tsx b/packages/use-request/demo/loadingDelay.tsx index 3520a335b3..2de1835fde 100644 --- a/packages/use-request/demo/loadingDelay.tsx +++ b/packages/use-request/demo/loadingDelay.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过设置 `options.loadingDelay` ,可以延迟 `loading` 变成 `true` 的时间,有效防止闪烁。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Spin, Button } from 'antd'; import React from 'react'; diff --git a/packages/use-request/demo/manual.tsx b/packages/use-request/demo/manual.tsx index 2669d43a54..a45386ecdd 100644 --- a/packages/use-request/demo/manual.tsx +++ b/packages/use-request/demo/manual.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过设置 `options.manual = true` , 则需要手动调用 `run` 时才会触发执行异步函数。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Button, Input, message } from 'antd'; import React, { useState } from 'react'; diff --git a/packages/use-request/demo/mutate.tsx b/packages/use-request/demo/mutate.tsx index 96d5ca38d1..8b82c0f9c5 100644 --- a/packages/use-request/demo/mutate.tsx +++ b/packages/use-request/demo/mutate.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 你可以通过 `mutate` ,直接修改 `data` 。 `mutate` 函数参数可以为 `newData` 或 `(oldData)=> newData` 。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Button, Input, message } from 'antd'; import React, { useState } from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/pagination-1.tsx b/packages/use-request/demo/pagination-1.tsx index 042138e411..b904af4187 100644 --- a/packages/use-request/demo/pagination-1.tsx +++ b/packages/use-request/demo/pagination-1.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 普通的分页场景,我们会自动管理 `current` 和 `pageSize`。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import React from 'react'; import { List, Pagination } from 'antd'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/pagination-antd.tsx b/packages/use-request/demo/pagination-antd.tsx index a47b288a7b..54f473f6c9 100644 --- a/packages/use-request/demo/pagination-antd.tsx +++ b/packages/use-request/demo/pagination-antd.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 由于 antd [Table](https://ant.design/components/table-cn/) 使用比较广泛,我们特别支持了 antd Table 需要的分页格式,及 `sorter` 、 `filters` 等。你可以通过 `result.tableProps` , `result.params[0]?.filters` , `result.params[0]?.sorter` 访问到这些属性。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import React from 'react'; import { Table, Button } from 'antd'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/pagination-cache.tsx b/packages/use-request/demo/pagination-cache.tsx index af1bdeb89d..fa45bd6723 100644 --- a/packages/use-request/demo/pagination-cache.tsx +++ b/packages/use-request/demo/pagination-cache.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 在 `cacheKey` 场景下, `run` 的参数 `params` 是可以缓存的,利用这个特点,我们可以实现 pagination 相关条件的缓存。 */ -import { useBoolean, useRequest, useUpdateEffect } from '@umijs/hooks'; +import { useBoolean, useRequest, useUpdateEffect } from 'ahooks'; import { Button, List, Pagination, Select } from 'antd'; import React, { useState } from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/polling.tsx b/packages/use-request/demo/polling.tsx index df3f38460d..f3571866c3 100644 --- a/packages/use-request/demo/polling.tsx +++ b/packages/use-request/demo/polling.tsx @@ -15,7 +15,7 @@ * - 在 `options.manual=true` 时,需要第一次执行 `run` 后,才开始轮询。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Button, Spin } from 'antd'; import React from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/preload.tsx b/packages/use-request/demo/preload.tsx index 6855875de8..998b47d5cd 100644 --- a/packages/use-request/demo/preload.tsx +++ b/packages/use-request/demo/preload.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 同一个 `cacheKey` 的请求,是全局共享的,也就是你可以提前加载数据。利用该特性,可以很方便的实现预加载。 */ -import { useBoolean, useRequest } from '@umijs/hooks'; +import { useBoolean, useRequest } from 'ahooks'; import { Button, Spin } from 'antd'; import React from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/refreshDeps.tsx b/packages/use-request/demo/refreshDeps.tsx index 0b9665f325..f8f83d3fd7 100644 --- a/packages/use-request/demo/refreshDeps.tsx +++ b/packages/use-request/demo/refreshDeps.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 当 `options.refreshDeps` 变化时,useRequest 会使用之前的参数重新执行 service。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Spin, Select } from 'antd'; import React, { useState } from 'react'; diff --git a/packages/use-request/demo/refreshOnWindowFocus.tsx b/packages/use-request/demo/refreshOnWindowFocus.tsx index d24718122f..f2ae5cf1d1 100644 --- a/packages/use-request/demo/refreshOnWindowFocus.tsx +++ b/packages/use-request/demo/refreshOnWindowFocus.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 如果你设置了 `options.refreshOnWindowFocus = true` ,则在浏览器窗口 `refocus` 和 `revisible` 时,会重新发起请求。你可以通过设置 `options.focusTimespan` 来设置请求间隔,默认为 `5000ms` 。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Spin } from 'antd'; import React from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/throttle.tsx b/packages/use-request/demo/throttle.tsx index 0c70ace557..fe14ccabbe 100644 --- a/packages/use-request/demo/throttle.tsx +++ b/packages/use-request/demo/throttle.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 通过设置 `options.throttleInterval` ,则进入节流模式。此时如果频繁触发 `run` ,则会以节流策略进行请求。 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import { Select } from 'antd'; import React from 'react'; import Mock from 'mockjs'; diff --git a/packages/use-request/demo/umiRequest.tsx b/packages/use-request/demo/umiRequest.tsx index 5ce110b3a6..d799da5953 100644 --- a/packages/use-request/demo/umiRequest.tsx +++ b/packages/use-request/demo/umiRequest.tsx @@ -6,7 +6,7 @@ * desc.zh-CN: 如果 useRequest 第一个参数是字符串,则默认使用 umi-request 发送网络请求 */ -import { useRequest } from '@umijs/hooks'; +import { useRequest } from 'ahooks'; import React from 'react'; export default () => { diff --git a/packages/use-request/index.en-US.md b/packages/use-request/index.en-US.md index 0a0b5c5533..5b253a5949 100644 --- a/packages/use-request/index.en-US.md +++ b/packages/use-request/index.en-US.md @@ -346,7 +346,7 @@ const { You can set global options at the outermost level of the project via `UseAPIProvider`. ```javascript -import {UseAPIProvider} from '@umijs/use-request'; +import {UseAPIProvider} from '@ahooksjs/use-request'; export function ({children})=>{ return ( @@ -385,7 +385,7 @@ You can configure the `request` after processing by `requsetMehod`. ```javascript // your request import { request } from '@/utils/request'; -import { UseAPIProvider } from '@umijs/use-request'; +import { UseAPIProvider } from '@ahooksjs/use-request'; { return ( @@ -387,7 +387,7 @@ const secondRequest = useReqeust(service); ```javascript // 你自己封装的 request import { request } from '@/utils/request'; -import { UseAPIProvider } from '@umijs/use-request'; +import { UseAPIProvider } from '@ahooksjs/use-request';