摘要:而每次捕獲出的錯(cuò)誤可能需要打印出來以檢測(cè)。同時(shí)有些同學(xué)不習(xí)慣使用來捕獲錯(cuò)誤,這就可能造成不可預(yù)計(jì)的問題。是否立即請(qǐng)求并接受初始化返回值業(yè)務(wù)我們并不希望初始化的是否立即發(fā)送請(qǐng)求。
前言發(fā)送服務(wù)端請(qǐng)求所面臨的問題自 React Hooks 16.8.0 后帶來了 React hooks 這一特性。這一特性在沒有破壞性的更新下為我們帶來了更加舒爽的開發(fā)方式。過去我們常常因providers,consumers,高階組件,render props 等形成“嵌套地獄”。盡管 Class Component 在某種程度上為我們提供了更方便的寫法以及生命周期,但同時(shí)也帶來了一些不好的地方。例如難以理解的 class 內(nèi)部原理、難以測(cè)試的聲明周期。而 React Hooks 為我們提供了一種 Function Component 的寫法,讓我們用更少的代碼寫出更加優(yōu)雅、易懂的代碼。本文不做 React Hooks API的講述,如有不懂,請(qǐng)移步 Hooks 簡介
在開發(fā)代碼時(shí),我們發(fā)送后端請(qǐng)求后接受到的數(shù)據(jù),需要使用try/catch來捕獲錯(cuò)誤。而每次捕獲出的錯(cuò)誤可能需要打印出來以檢測(cè)bug。這樣我們每次都會(huì)寫同樣的代碼,這樣在開發(fā)過程中很不友好。同時(shí)有些同學(xué)不習(xí)慣使用 try/catch 來捕獲錯(cuò)誤,這就可能造成不可預(yù)計(jì)的問題。
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中展示了在業(yè)務(wù)場(chǎng)景中發(fā)送請(qǐng)求的場(chǎng)景,當(dāng)發(fā)送請(qǐng)求多了之后我們會(huì)每次手動(dòng)try / catch,雖然不是大問題,但是重復(fù)代碼寫多了會(huì)覺得難受...。下面看第二個(gè)功能。
在實(shí)際的業(yè)務(wù)場(chǎng)景中,我們向后端發(fā)送請(qǐng)求時(shí),往往伴隨著用戶點(diǎn)擊多次,但是只能發(fā)送一次請(qǐng)求的問題,這時(shí)我們需要手動(dòng)加鎖。并且在很多場(chǎng)景中我們需要知道請(qǐng)求狀態(tài)來為頁面設(shè)置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}
// 數(shù)據(jù)是否正在加載,以此來判斷是否需要展示loading
loading={loading}
/>
)
}
demo中展示了日期組件以及包含有分頁器的 Table組件,當(dāng)日期發(fā)生變更,或者分頁器發(fā)生變更時(shí),我們需要dispatch來更新請(qǐng)求參數(shù),從而發(fā)送請(qǐng)求。在發(fā)送請(qǐng)求時(shí)如果正在請(qǐng)求,則忽略,而不在請(qǐng)求時(shí)需要手動(dòng)加鎖,來防止多次請(qǐng)求。
同時(shí)Table需要根據(jù)請(qǐng)求狀態(tài)來判斷是否需要展示loading。
解決問題
基于以上的問題,我們能否通過 Hooks 來封裝一個(gè) custom hooks來解決問題。
1. 明確目標(biāo)
custom hooks 解決的問題
解決每個(gè)函數(shù)都要統(tǒng)一寫try/catch的流程
解決發(fā)送請(qǐng)求需要手動(dòng)加鎖防止多次重復(fù)請(qǐng)求的痛點(diǎn)
不需要在手動(dòng)useState loading,直接獲取loading值
所以我們需要在 custom hooks 中發(fā)送請(qǐng)求、暴露出請(qǐng)求后的值、暴露 loading 狀態(tài)、以及用戶可能需要多次請(qǐng)求,這就需要暴露一個(gè)勾子。在發(fā)生請(qǐng)求錯(cuò)誤時(shí)可能需要做某些操作,所以還需要暴露在錯(cuò)誤時(shí)回調(diào)的勾子函數(shù)。
是否立即請(qǐng)求并接受初始化返回值
業(yè)務(wù)我們并不希望初始化的是否立即發(fā)送請(qǐng)求。
并且能夠有初始化的返回值
支持泛型
在TS中,開發(fā)者希望能夠自定義請(qǐng)求的參數(shù)類型,以及請(qǐng)求結(jié)果的類型
2. 定義函數(shù)
useFetch 函數(shù)
import { useState, useEffect } from "react";
/**
* 1. 解決每個(gè)函數(shù)都要統(tǒng)一寫try/catch的流程
* 2. 解決發(fā)送請(qǐng)求需要手動(dòng)加鎖防止多次重復(fù)請(qǐng)求的痛點(diǎn)
* 3. 不需要在手動(dòng)useState loading了~,直接獲取fetching值
* 4. (甚至在參數(shù)發(fā)生變化時(shí)只需要傳入更改的參數(shù)就OK)已刪除
* @param getFunction 發(fā)送請(qǐng)求的函數(shù)
* @param params 參數(shù)
* @param initRes 初始化值
* @param execute 是否立即執(zhí)行請(qǐng)求函數(shù)
*/
// R, P支持泛型
function UseFetch(
getFunction: any,
params: P,
initRes");
3. 如何使用
根據(jù)最初的demo我們改造一下代碼
import React, { useCallback, useReducer, useEffect } from "react"
import { TimeNumberType, PageType } from "common/constant/interface"
import { DateRangePicker, Table } from "UI"
// 導(dǎo)入 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}
// 數(shù)據(jù)是否正在加載,以此來判斷是否需要展示loading
loading={loading}
/>
)
}
對(duì)比代碼我們可以看到中間的請(qǐng)求的代碼被我們干掉了,使用 useFetch 來將狀態(tài)以及發(fā)送請(qǐng)求封裝在一起。能夠讓我們寫更少的代碼。
同時(shí) useFetch的第3個(gè)參數(shù)當(dāng)傳入的為 null 時(shí),可以模擬請(qǐng)求發(fā)送錯(cuò)誤,這樣我們可以在開發(fā)時(shí)做兜底方案。
4. 也許并不想要那么多值。
也許有些請(qǐng)求不需要關(guān)注請(qǐng)求狀態(tài)
// 解構(gòu)賦值、空著就好
const [list, , getList] = useFetch(
getWithDraw,
state,
{ list: [], total: 0 },
false
)
本文完~
如有問題,歡迎指出~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/6780.html
相關(guān)文章
-
React Hooks 從入門到上手
摘要:前言樓主最近在整理的一些資料,為項(xiàng)目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個(gè)初始值,比如,這個(gè)按鈕的最初要顯示的是。取代了提供了一個(gè)統(tǒng)一的。
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 從入門到上手
摘要:前言樓主最近在整理的一些資料,為項(xiàng)目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個(gè)初始值,比如,這個(gè)按鈕的最初要顯示的是。取代了提供了一個(gè)統(tǒng)一的。
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 異步數(shù)據(jù)管理思考
摘要:異步數(shù)據(jù)管理一直是前端的一個(gè)重點(diǎn)和難點(diǎn),可以這么說,的應(yīng)用會(huì)有異步數(shù)請(qǐng)求據(jù)并在中消費(fèi),并且在相當(dāng)多的應(yīng)用中,處理異步數(shù)據(jù)是它的核心業(yè)務(wù)邏輯??偨Y(jié)個(gè)人認(rèn)為,異步數(shù)據(jù)不應(yīng)該使用狀態(tài)管理來維護(hù),應(yīng)該放在組件內(nèi)。
異步數(shù)據(jù)管理一直是前端的一個(gè)重點(diǎn)和難點(diǎn),可以這么說,80%的 web 應(yīng)用會(huì)有異步數(shù)請(qǐng)求據(jù)并在 UI 中消費(fèi),并且在相當(dāng)多的 web 應(yīng)用中,處理異步數(shù)據(jù)是它的核心業(yè)務(wù)邏輯。
在 R...
-
React Hooks 入門(2019)
摘要:到目前為止,表達(dá)這種流程的基本形式是課程。按鈕依次響應(yīng)并更改獲取更新的文本。事實(shí)證明不能從返回一個(gè)??梢栽诮M件中使用本地狀態(tài),而無需使用類。替換了提供統(tǒng)一,和。另一方面,跟蹤中的狀態(tài)變化確實(shí)很難。
備注:為了保證的可讀性,本文采用意譯而非直譯。
在這個(gè) React鉤子 教程中,你將學(xué)習(xí)如何使用 React鉤子,它們是什么,以及我們?yōu)槭裁催@樣做!
showImg(https://segm...
-
精讀《Function Component 入門》
摘要:比如就是一種,它可以用來管理狀態(tài)返回的結(jié)果是數(shù)組,數(shù)組的第一項(xiàng)是值,第二項(xiàng)是賦值函數(shù),函數(shù)的第一個(gè)參數(shù)就是默認(rèn)值,也支持回調(diào)函數(shù)。而之所以輸出還是正確的,原因是的回調(diào)函數(shù)中,值永遠(yuǎn)指向最新的值,因此沒有邏輯漏洞。
1. 引言
如果你在使用 React 16,可以嘗試 Function Component 風(fēng)格,享受更大的靈活性。但在嘗試之前,最好先閱讀本文,對(duì) Function Com...
發(fā)表評(píng)論
0條評(píng)論
Ryan_Li
男|高級(jí)講師
TA的文章
閱讀更多
anaconda3安裝tensorflow
閱讀 2977·2023-04-25 17:46
為什么有的網(wǎng)站需要做CND加速呢?
閱讀 3605·2021-11-25 09:43
漫畫 | 被TDD/BDD/DDD......“逼瘋”的程序員
閱讀 1106·2021-11-18 10:02
谷歌對(duì)14,000 名受到網(wǎng)絡(luò)安全威脅的 Gmail 用戶發(fā)出警告
閱讀 3068·2021-10-14 09:43
?函數(shù)解析?|memset()函數(shù)的原理
閱讀 2789·2021-10-13 09:40
HR:這樣的簡歷我看5秒就扔了
閱讀 1537·2021-09-28 09:35
微信小程序組件—wxui的使用
閱讀 2200·2019-08-30 15:52
前端面試題-BFC(塊格式化上下文)
閱讀 3169·2019-08-30 14:06
閱讀需要支付1元查看