前言
越来越多的项目 使用 react hooks 的方式来开发应用,需要调用 api 请求数据,一个网络请求的自定义 hook 显得尤为的重要
很久没用到的 redux
我接触的项目中,大多数引入了 react-redux, redux 之类的状态管理库,用来做 数据 与 UI 分离,自己感觉是为了用而用,太重又没必要,当然,也可能自己做的都是小项目,体会不到好处,既然体会不到,为啥我要用,以前请求个数据,数据流要绕一大圈
首先是 view
1 | @connect( |
Action
1 | function getData() { |
Reducer
1 | function reducer(state) { |
这是一个最基本的 redux 代码,还没有算上 redux-saga
, 和 isLoading
, isError
之类的 action, 有时候我们写代码都忘记初心了。.., 那就是 我只是想请求一个数据
, 现实是不管用不用 store, 我都和他 redux 的世界里走一走
单纯的发一个请求吧,求求你了
1 | import MyFetcher from './index.ts'; |
一个网络请求基本场景
- 需要一个是否在请求的标识,用来 loading 状态
- 需要一个请求完成后的数据,用来渲染
- 需要一个是否错误的标识,或错误信息,用来做错误的逻辑
- 最好有一个支持重新请求的功能
- 最好在组件卸载的时候,能够自动取消当前的请求
基本实现
我们这里基于 axios
来实现,取名 useData
首先定义三个状态机 loading
, data
, error
1 | function useData<T extends any[] = [], E = null>() { |
然后声明一个 请求函数,
- 在请求开始 设置
loading
为true
- 请求成功,成功 setData
- 请求失败,设置 setError
- 完成,设置
loading
为false
1 | import axios from 'axios'; |
将 url
作为 useEffect
的依赖项,这样就可以在 url
改变的时候,自动重新拉取数据,非常方便,最后对 fetchData
引用,实现 refresh
重新加载的功能
使用
1 | function App() { |
可以很明显的看出,React Hooks
很好的解决了 逻辑复用的问题,我们通过这样一个 自定义 hook
, 实现了一个可以重新拉取数据,加载状态,错误状态,显示数据的公用 hook, 然后还要一个问题,useData
内部写死了 axios
的 get
请求,显然是不合理,为了支持自定义的网络请求库,我们可以添加第二个参数,来实现自己的 fetcher
自定义 fetcher
1 | + function useData<T extends any[] = [], E = null>(url: string, fetcher: (url: string) => Promise<T>) { |
这样,就可以传入自己的网络请求实现,比如 fetch
1 | function App() { |
当然这只是一个简单的封装,事实上,社区已经有一个很火的 hooks 请求库 swr, 非常实用,推荐给大家哟 :)