在上篇文章我们讲了如何使用 React 的 Suspense 组件和 lazy 方法来实现模块的懒加载,后面还讲了如何使用
React 的 useState 方法来实现自定义的 Hooks,从而达到复用的目的。
我们知道,不管在做什么样的前端项目,列表页肯定是存在的,那如何获取列表的数据呢?大部分情况下我们都是在每个模块内部自己实现一个获取数据的方法,然后调用 setState 来更新数据。那有没有更好的方式可以做到这些,并且能够在一个项目中处处复用这个功能呢?答案就是使用 React Hooks。
useEffect 介绍
简单的说,useEffect 就是在组件挂载完成或者更新完成的时候,需要执行的一系列操作,这些操作可能是 ajax 请求,dom 操作,事件处理等等。
官方文档里面有句话说的是,useEffect 是 componentDidMount, componentDidUpdate, 和 componentWillUnmount 三个生命周期钩子的组合,那就是之前分别在这三个地方干的事情,现在可以统一在一个地方干了,是不是很方便?。为了保证文章简洁,这里不过多介绍,有需要可以参考官方文档
useReducer 介绍
如果你用过 redux,那你应该知道 redux 就是通过 reducer 来处理 dispatch 出来的各种 action 的。每个 reducer 都是一个纯函数,处理完成之后,返回新的 state,然后触发 React 的更新。官方文档
自定义一个获取数据的 React Hooks
先来分析下,我们要从服务器获取数据,需要做哪些事情。
- 构造请求参数
- 发送请求
- 解析返回结果或异常处理
- 展示结果或异常错误提示
从上面的几个点我们可以分析出,我们的自定义 Hook 要能够传入请求人 url 以及请求的参数,在请求失败的时候能够有后台返回的提示信息,在请求成功的时候能够返回后台返回的数据,我们还需要知道请求是否失败。
这里我们将 action 拆分为 3 个:
- FETCH_INIT // 开始加载数据,用来展示 Loading 状态
- FETCH_SUCCESS // 加载数据成功,用来展示数据
- FETCH_ERROR // 加载数据失败,用来展示错误信息
基于上面的分析,我们先定义一个 reducer,用来处理每个 action。
reducer.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
export const dataFetchReducer = (state: any, action: {[type: string]: any}) => { switch(action.type) { case 'FETCH_INIT': return { ...state, isLoading: true, isError: false } case 'FETCH_SUCCESS': return { ...state, isLoading: false, isError: false, data: action.payload } case 'FETCH_ERROR': return { ...state, isLoading: false, isError: true, msg: action.payload } default: throw new Error(`Unsupport action type:${action.type}`); } } |