react-hooks封装-发送请求初始化
使用技术为
redux
+(ts
/js
)
因发送请求获取数据的逻辑基本一致,所以将其封装为自定义hooks,用以简化代码
检查
首先检查原代码,两段代码的逻辑相同,都是用dispatch派发请求,然后使用useSelect获取store中的数据。
`Profile.tsx`
const dispatch = useDispatch()
useEffect(() => {
dispatch(getUser())
}, [dispatch])
const user = useSelector((state: RootState) => state.profile.user)
`Edit.tsx`
const dispatch = useDispatch()
useEffect(() => {
dispatch(getUserProfile())
}, [dispatch])
const userProfile = useSelector((state: RootState) => state.profile.userProfile)
分析
分析要封装的代码逻辑,找到相同点和不同点。
函数封装的基本思想:将相同的逻辑直接拷贝到函数中,不同的逻辑通过函数参数传入。需要返回数据,就通过函数返回值返回。
-
相同点
有以下相同代码
-
不同点
- 需要派发的函数不同
- 需要返回的状态不同
-
结论
-
自定义hooks的参数就是需要派发的函数和需要返回的状态名
-
自定义hooks的返回值就是需要返回的状态
-
所以得到以下简易代码
const useInitialState = (action, stateName) => {
// 需要复用的状态逻辑代码
return state
}
// 使用自定义 hooks:
const { userProfile } = useInitState(getUserProfile, 'profile')
const { user } = useInitialState(getUser, 'profile')
优化
js版本–无类型约束
将相同的逻辑,直接封装到 useInitState 函数中
useInitState.ts
// 导入依赖的包
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from '@/types/store'
// action:需要派发的函数名 stateName:需要获取的状态名 return状态值
export default function useInitialState (action, stateName) {
const dispatch = useDispatch()
useEffect(() => {
dispatch(action())
}, [dispatch])
return useSelector((state:RootState) => state[stateName])
}
ts版本–有类型约束
- 参数 action:
- 就是一个函数,所以,直接指定为最简单的函数类型即可
- 参数 stateName:
- stateName 表示从 Redux 状态中取出的状态名称,比如,
'profile'
- 所以,stateName 应该是 RootState 中的所有状态名称中的任意一个
useInitState.ts
// 1. 泛型K 继承自RootState 的key 值
// 2. RootState 为store 状态的总线
// 3. keyof 获取RootState 的所有状态名的类型
// 4. 将K 赋值给stateName 的状态
// 5. 返回相应状态名的值
// action:需要派发的函数名 stateName:需要获取的状态名 return状态值
export default function useInitialState (
action: () => void,
stateName: K
) {
const dispatch = useDispatch()
useEffect(() => {
dispatch(action())
}, [dispatch])
return useSelector((state: RootState) => state[stateName])
}
使用
Edit.tsx
import { useInitState } from '@/hooks/useInitState'
const { userProfile } = useInitState(getUserProfile, 'profile')