摘要:而每次捕獲出的錯誤可能需要打印出來以檢測。同時有些同學不習慣使用來捕獲錯誤,這就可能造成不可預計的問題。是否立即請求并接受初始化返回值業務我們并不希望初始化的是否立即發送請求。
前言發送服務端請求所面臨的問題自 React Hooks 16.8.0 后帶來了 React hooks 這一特性。這一特性在沒有破壞性的更新下為我們帶來了更加舒爽的開發方式。過去我們常常因providers,consumers,高階組件,render props 等形成“嵌套地獄”。盡管 Class Component 在某種程度上為我們提供了更方便的寫法以及生命周期,但同時也帶來了一些不好的地方。例如難以理解的 class 內部原理、難以測試的聲明周期。而 React Hooks 為我們提供了一種 Function Component 的寫法,讓我們用更少的代碼寫出更加優雅、易懂的代碼。本文不做 React Hooks API的講述,如有不懂,請移步 Hooks 簡介
在開發代碼時,我們發送后端請求后接受到的數據,需要使用try/catch來捕獲錯誤。而每次捕獲出的錯誤可能需要打印出來以檢測bug。這樣我們每次都會寫同樣的代碼,這樣在開發過程中很不友好。同時有些同學不習慣使用 try/catch 來捕獲錯誤,這就可能造成不可預計的問題。
import React, { useCallback, useReducer, useEffect } from "react"
import { TimeNumberType, PageType } from "common/constant/interface"
type ParamsType = PageType & TimeNumberType
const reducer = (state: ParamsType, action: Actions) => {
const { payload } = action
return { ...state, ...payload }
}
const postListData = (params: ParamsType) => post("/network/api/test/getlist", params)
const initialParams = {
pageSize: 10,
pageNumber: 1,
startTime: 0,
endTime: 0
}
const ListComponent = () => {
const [params, dispatch] = useReducer(reducer, initialState)
const getList = async () => {
// try catch
try {
const res = await postListData(params)
console.log(res)
} catch (err) {
console.error(err)
}
}
useEffect(() => {
getList()
}, [params])
}
demo中展示了在業務場景中發送請求的場景,當發送請求多了之后我們會每次手動try / catch,雖然不是大問題,但是重復代碼寫多了會覺得難受...。下面看第二個功能。
在實際的業務場景中,我們向后端發送請求時,往往伴隨著用戶點擊多次,但是只能發送一次請求的問題,這時我們需要手動加鎖。并且在很多場景中我們需要知道請求狀態來為頁面設置loading。例如:
import React, { useCallback, useReducer, useEffect } from "react"
import { TimeNumberType, PageType } from "common/constant/interface"
import { DateRangePicker, Table } from "UI"
type ParamsType = PageType & TimeNumberType
const TIME = Symbol("time")
const PAGE = Symbol("page")
const reducer = (state: ParamsType, action: Actions) => {
const { payload } = action
return { ...state, ...payload }
}
const postListData = (params: ParamsType) => post("/network/api/test/getlist", params)
const initialParams = {
pageSize: 10,
pageNumber: 1,
startTime: 0,
endTime: 0
}
const ListComponent = () => {
const [params, dispatch] = useReducer(reducer, initialState)
const [loading, setLoading] = useState(false)
const [list, setList] = useState({})
const getList = async () => {
// loading is true
if (loading) return
// set loading status
setLoading(true)
// try catch
try {
const res = await postListData(params)
setList(res)
setLoading(false)
} catch (err) {
console.error(err)
setLoading(false)
}
}
useEffect(() => {
getList()
}, [params])
return (
{
dispatch({ payload: { pageNumber }, type: PAGE })
}}
list={list}
// 數據是否正在加載,以此來判斷是否需要展示loading
loading={loading}
/>
)
}
demo中展示了日期組件以及包含有分頁器的 Table組件,當日期發生變更,或者分頁器發生變更時,我們需要dispatch來更新請求參數,從而發送請求。在發送請求時如果正在請求,則忽略,而不在請求時需要手動加鎖,來防止多次請求。
同時Table需要根據請求狀態來判斷是否需要展示loading。
解決問題
基于以上的問題,我們能否通過 Hooks 來封裝一個 custom hooks來解決問題。
1. 明確目標
custom hooks 解決的問題
解決每個函數都要統一寫try/catch的流程
解決發送請求需要手動加鎖防止多次重復請求的痛點
不需要在手動useState loading,直接獲取loading值
所以我們需要在 custom hooks 中發送請求、暴露出請求后的值、暴露 loading 狀態、以及用戶可能需要多次請求,這就需要暴露一個勾子。在發生請求錯誤時可能需要做某些操作,所以還需要暴露在錯誤時回調的勾子函數。
是否立即請求并接受初始化返回值
業務我們并不希望初始化的是否立即發送請求。
并且能夠有初始化的返回值
支持泛型
在TS中,開發者希望能夠自定義請求的參數類型,以及請求結果的類型
2. 定義函數
useFetch 函數
import { useState, useEffect } from "react";
/**
* 1. 解決每個函數都要統一寫try/catch的流程
* 2. 解決發送請求需要手動加鎖防止多次重復請求的痛點
* 3. 不需要在手動useState loading了~,直接獲取fetching值
* 4. (甚至在參數發生變化時只需要傳入更改的參數就OK)已刪除
* @param getFunction 發送請求的函數
* @param params 參數
* @param initRes 初始化值
* @param execute 是否立即執行請求函數
*/
// R, P支持泛型
function UseFetch(
getFunction: any,
params: P,
initRes");
3. 如何使用
根據最初的demo我們改造一下代碼
import React, { useCallback, useReducer, useEffect } from "react"
import { TimeNumberType, PageType } from "common/constant/interface"
import { DateRangePicker, Table } from "UI"
// 導入 useFetch
import { useFetch } from "custom-hooks"
type ParamsType = PageType & TimeNumberType
type ListInfo = {list: Array, total: number}
const TIME = Symbol("time")
const PAGE = Symbol("page")
const reducer = (state: ParamsType, action: Actions) => {
const { payload } = action
return { ...state, ...payload }
}
const postListData = (params: ParamsType) => post("/network/api/test/getlist", params)
const initialParams = {
pageSize: 10,
pageNumber: 1,
startTime: 0,
endTime: 0
}
const ListComponent = () => {
const [params, dispatch] = useReducer(reducer, initialState)
const [list, loading, getList] = useFetch(
getWithDraw,
state,
{ list: [], total: 0 },
false
)
useEffect(() => {
getList()
}, [params])
return (
{
dispatch({ payload: { pageNumber }, type: PAGE })
}}
list={list}
// 數據是否正在加載,以此來判斷是否需要展示loading
loading={loading}
/>
)
}
對比代碼我們可以看到中間的請求的代碼被我們干掉了,使用 useFetch 來將狀態以及發送請求封裝在一起。能夠讓我們寫更少的代碼。
同時 useFetch的第3個參數當傳入的為 null 時,可以模擬請求發送錯誤,這樣我們可以在開發時做兜底方案。
4. 也許并不想要那么多值。
也許有些請求不需要關注請求狀態
// 解構賦值、空著就好
const [list, , getList] = useFetch(
getWithDraw,
state,
{ list: [], total: 0 },
false
)
本文完~
如有問題,歡迎指出~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/6780.html
相關文章
-
React Hooks 從入門到上手
摘要:前言樓主最近在整理的一些資料,為項目重構作準備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統一的。
showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550);
Hooks are a new addition in React 16.8. They let you use sta...
-
React Hooks 從入門到上手
摘要:前言樓主最近在整理的一些資料,為項目重構作準備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統一的。
showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550);
Hooks are a new addition in React 16.8. They let you use sta...
-
React 異步數據管理思考
摘要:異步數據管理一直是前端的一個重點和難點,可以這么說,的應用會有異步數請求據并在中消費,并且在相當多的應用中,處理異步數據是它的核心業務邏輯。總結個人認為,異步數據不應該使用狀態管理來維護,應該放在組件內。
異步數據管理一直是前端的一個重點和難點,可以這么說,80%的 web 應用會有異步數請求據并在 UI 中消費,并且在相當多的 web 應用中,處理異步數據是它的核心業務邏輯。
在 R...
-
React Hooks 入門(2019)
摘要:到目前為止,表達這種流程的基本形式是課程。按鈕依次響應并更改獲取更新的文本。事實證明不能從返回一個。可以在組件中使用本地狀態,而無需使用類。替換了提供統一,和。另一方面,跟蹤中的狀態變化確實很難。
備注:為了保證的可讀性,本文采用意譯而非直譯。
在這個 React鉤子 教程中,你將學習如何使用 React鉤子,它們是什么,以及我們為什么這樣做!
showImg(https://segm...
-
精讀《Function Component 入門》
摘要:比如就是一種,它可以用來管理狀態返回的結果是數組,數組的第一項是值,第二項是賦值函數,函數的第一個參數就是默認值,也支持回調函數。而之所以輸出還是正確的,原因是的回調函數中,值永遠指向最新的值,因此沒有邏輯漏洞。
1. 引言
如果你在使用 React 16,可以嘗試 Function Component 風格,享受更大的靈活性。但在嘗試之前,最好先閱讀本文,對 Function Com...
發表評論
0條評論
Ryan_Li
男|高級講師
TA的文章
閱讀更多
anaconda3安裝tensorflow
閱讀 2959·2023-04-25 17:46
為什么有的網站需要做CND加速呢?
閱讀 3588·2021-11-25 09:43
漫畫 | 被TDD/BDD/DDD......“逼瘋”的程序員
閱讀 1092·2021-11-18 10:02
谷歌對14,000 名受到網絡安全威脅的 Gmail 用戶發出警告
閱讀 3051·2021-10-14 09:43
?函數解析?|memset()函數的原理
閱讀 2767·2021-10-13 09:40
HR:這樣的簡歷我看5秒就扔了
閱讀 1524·2021-09-28 09:35
微信小程序組件—wxui的使用
閱讀 2184·2019-08-30 15:52
前端面試題-BFC(塊格式化上下文)
閱讀 3154·2019-08-30 14:06
閱讀需要支付1元查看