1. 程式人生 > 其它 >react-hooks封裝-傳送請求初始化

react-hooks封裝-傳送請求初始化

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)

分析

分析要封裝的程式碼邏輯,找到相同點和不同點。
函式封裝的基本思想:將相同的邏輯直接拷貝到函式中,不同的邏輯通過函式引數傳入。需要返回資料,就通過函式返回值返回。

  1. 相同點

    有以下相同程式碼

  1. 不同點

    1. 需要派發的函式不同
    2. 需要返回的狀態不同
  2. 結論

    1. 自定義hooks的引數就是需要派發的函式和需要返回的狀態名

    2. 自定義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版本–有型別約束

  1. 引數 action:
  • 就是一個函式,所以,直接指定為最簡單的函式型別即可
  1. 引數 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<K extends keyof RootState> (
  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')