AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

useEffect 實踐案例:自定義 Hook

來源: 責編: 時間:2023-12-21 17:11:29 217觀看
導讀我們將在上一章案例的基礎之上學習自定義 hook。在上一章中,我們巧妙的把大量的 JSX 邏輯處理封裝在了 List 組件中,使得在頁面組件的代碼變得非常簡單。這是針對 UI 層的邏輯處理,那么在數據的處理上,是否也能夠進行一些

VVw28資訊網——每日最新資訊28at.com

我們將在上一章案例的基礎之上學習自定義 hook。VVw28資訊網——每日最新資訊28at.com

在上一章中,我們巧妙的把大量的 JSX 邏輯處理封裝在了 List 組件中,使得在頁面組件的代碼變得非常簡單。這是針對 UI 層的邏輯處理,那么在數據的處理上,是否也能夠進行一些封裝呢?VVw28資訊網——每日最新資訊28at.com

// 數據的主要核心邏輯const str = useRef('')const [list, setList] = useState<string[]>([])const [error, setError] = useState('')const [loading, setLoading] = useState(true)function getList() {  searchApi(str.current).then(res => {    setList(res)    setLoading(false)    setError('')  }).catch(err => {    setLoading(false)    setError(err)  })}useEffect(() => {  loading && getList()}, [loading])function onSure() {  setLoading(true)}

答案是肯定的,解決方案就是我們將要在本章中學習的自定義 hook。VVw28資訊網——每日最新資訊28at.com

一、自定義hook

我們常常會封裝一個函數用于邏輯的復用。自定義 hook 也是這樣的一個在 react 組件內部用于邏輯復用的函數封裝。VVw28資訊網——每日最新資訊28at.com

和普通函數封裝相比,他唯一的特殊之處就在于我們常常會將 react 內置 hook 封裝在邏輯之中,比如 useState,useEffect 等。除此之外,為了區分與普通的函數封裝,我們必須以 use 開頭為自定義 hook 命名,這樣的 hook 只能在 React 組件中使用。VVw28資訊網——每日最新資訊28at.com

以上一章中的數據處理邏輯為例,我們來封裝一個自定義 hook,將其命名為 useFetch。VVw28資訊網——每日最新資訊28at.com

function useFetch() {}

我們先考慮單個場景的封裝,單純只是為了讓組件看上去更簡潔。VVw28資訊網——每日最新資訊28at.com

我們就可以把所有的數據和處理數據的邏輯封裝起來。VVw28資訊網——每日最新資訊28at.com

import {useEffect, useState, useRef} from 'react'import { searchApi } from './api'export default function useFetch() {  const str = useRef('')  const [list, setList] = useState<string[]>([])  const [error, setError] = useState('')  const [loading, setLoading] = useState(true)  function getList() {    searchApi(str.current).then(res => {      setList(res)      setLoading(false)      setError('')    }).catch(err => {      setLoading(false)      setError(err)    })  }  useEffect(() => {    loading && getList()  }, [loading])  return { str, list, error, loading, setLoading }}

封裝過程非常簡單,就是把之前那一堆邏輯全部遷移過來,最后返回應用組件里需要的數據和方法即可。VVw28資訊網——每日最新資訊28at.com

return { str, list, error, loading, setLoading }

OK,此時我們來觀察一下組件里的代碼。VVw28資訊網——每日最新資訊28at.com

export default function DemoOneNormal() {  const {loading, setLoading, str, list, error} = useFetch()    return (    <Block className={s.container} title={td.title} desc={td.desc}>      <div className={r.flex}>        <input          className={s.input}          placeholder="請輸入您要搜索的內容"          onChange={(e) => str.current = e.target.value}        />        <Button          className={s.button}          onClick={() => setLoading(true)}        >          搜索        </Button>      </div>      <List        list={list}        loading={loading}        error={error}        renderItem={(item) => (          <div key={item} className={s.item}>{item}</div>        )}      />    </Block>  )}

邏輯簡潔了許多。變成了簡單的同步代碼:通過一個方法獲取數據,并將數據渲染到 UI 組件。VVw28資訊網——每日最新資訊28at.com

Block 組件是單獨封裝的布局組件,希望不要因此造成任何理解上的困難。VVw28資訊網——每日最新資訊28at.com

一個組件變成了數據與UI的結合。我們分別將復雜的數據處理邏輯封裝在 hook 里,將復雜的UI交互邏輯封裝在基礎 UI 組件里,在使用時,利用他們的封裝結果進行組合,能夠簡單,高效的組合出復雜的頁面,這也是我們在實踐中最大的追求VVw28資訊網——每日最新資訊28at.com

這里有些人可能會有一些疑問,我只是把一些邏輯放在了另外的地方,代碼量最終不僅沒有減少,反而還變多了,這樣做的好處真的有那么大嗎?當然,因為我們封裝的 useFetch 和 List 組件,他們承載了大多數的復雜邏輯,并且只會在最開始的時候編寫一次,在以后的使用中,就直接引入使用就行了,這極大的簡化了后續的開發工作量,對工作效率的提高非常顯著VVw28資訊網——每日最新資訊28at.com

二、進一步思考

此時的封裝雖然足夠簡潔。但是沒有考慮復用。因此還需要進一步思考改進。VVw28資訊網——每日最新資訊28at.com

我們來分析一下場景:每一個需要信息展示的頁面,基本邏輯都是在初始化時,請求接口,獲得數據,然后展示信息。我們可以把不同情況的接口請求抽象成為一個接口,然后基于這個場景來思考不同頁面的請求的共性與差異。VVw28資訊網——每日最新資訊28at.com

每個頁面都要處理信息展示、異常等邏輯,差異的地方就在于獲取數據的 api 函數不一樣,他返回的數據內容,數據類型也不一樣。VVw28資訊網——每日最新資訊28at.com

不一樣的東西作為參數傳入,那我們只需要將 api 函數作為參數傳入即可。VVw28資訊網——每日最新資訊28at.com

const info = useFetch(searchApi)

不過我們此時還需要考慮的是,為了確保自定義 hook 的返回類型具備完整準確的類型推導,我們還需要約定傳入 api 的參數類型與返回類型。VVw28資訊網——每日最新資訊28at.com

因此,在定義 useFetch 時,我們先用 ts 約定 api 的具體類型,因為參數類型和返回值類型在封裝時都不確定,只能在具體的實參傳入之后才能明確,因此使用兩個泛型來分別表示參數類型和返回值類型。VVw28資訊網——每日最新資訊28at.com

type API<T, P>   = (param?: P) => Promise<T>

正常代碼不會這樣換行,之所以這樣只是為了在移動端能夠更多的展示代碼信息而不用滾動查看。VVw28資訊網——每日最新資訊28at.com

然后在定義 useFetch 時傳入這兩個泛型即可,完整代碼如下:VVw28資訊網——每日最新資訊28at.com

import { useEffect, useState, useRef } from 'react'type API<T, P> = (param?: P) => Promise<T>export default function useFetch<T, P>(api: API<T, P>) {  const param = useRef<P>()  const [list, setList] = useState<T>()  const [error, setError] = useState('')  const [loading, setLoading] = useState(true)  function getList() {    api(param.current).then(res => {      setList(res)      setLoading(false)      setError('')    }).catch(err => {      setLoading(false)      setError(err)    })  }  useEffect(() => {    loading && getList()  }, [loading])  return {     param,     setParam: (p: P) => param.current = p,    list,     error,     loading,     setLoading   }}

因為在使用時,傳入的 api 函數已經具備了完善的類型,因此我們這種寫法可以借助 ts 內部的自動推導而簡化使用時在 ts 上的繁瑣。VVw28資訊網——每日最新資訊28at.com

VVw28資訊網——每日最新資訊28at.com

const {  loading,   setLoading,   setParam,  list,  error} = useFetch(searchApi)

雖然在使用層面沒有任何 ts 的痕跡,但是返回值的類型已經非常明確。VVw28資訊網——每日最新資訊28at.com

VVw28資訊網——每日最新資訊28at.com

由于在封裝過程中我們沒有處理默認值的情況,因此返回類型可能為 undefined,這在實踐中一定要引起重視。你可以根據實際情況往 useFetch 傳入默認值,也可以在使用層面初始化默認值VVw28資訊網——每日最新資訊28at.com

const {  loading,   setLoading,   setParam,  list = [],  error} = useFetch(searchApi)

這樣,一個通用,高效,且具備準確類型提示的 hook 就被我們封裝好了。VVw28資訊網——每日最新資訊28at.com

在實踐過程中,由于不同的團隊有不同的需求,你還需要根據自己的需求和項目實際情況做相應的細節調整,切記不要完整套用。VVw28資訊網——每日最新資訊28at.com

三、取舍

由于面試的影響,讓不少前端同行錯誤的把性能當成了實踐中最重要的標準。但其實工作中性能并不是最高的優先級。我們往往會在可接受的范圍之內,犧牲性能換取其他的便利。VVw28資訊網——每日最新資訊28at.com

例如,多一層函數封裝,其實也就意味著執行壓力多那么一點點。但是他可能換來的是開發效率的極大提高。VVw28資訊網——每日最新資訊28at.com

因此,在我們的課程案例決策當中,提供的方案并不會把性能當做第一準則,代碼的可讀性、可維護性、開發效率的優先級都會比性能更高。只要我們在寫代碼的過程中,非常明確的知道這種方式我們舍棄了什么,得到了什么,你權衡之后,愿意做出這樣的取舍,那么這樣的方式就是可以使用的。VVw28資訊網——每日最新資訊28at.com

當然,性能依然非常重要,如果你的頁面出現了卡頓,我們就應該思考一下,是不是對性能的犧牲有點過了頭。VVw28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-51248-0.htmluseEffect 實踐案例:自定義 Hook

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 研發提效必備技能:25張圖手把手教你基于Docker搭建Maven私服倉庫

下一篇: 看完后,你再也不用怕面試問并發編程啦

標簽:
  • 熱門焦點
  • MIX Fold3包裝盒泄露 新機本月登場

    小米的全新折疊屏旗艦MIX Fold3將于本月發布,近日該機的真機包裝盒在網上泄露。從圖上來看,新的MIX Fold3包裝盒在外觀設計方面延續了之前的方案,變化不大,這也是目前小米旗艦
  • 8月總票房已突破10億!《封神》第一:口碑已經成了

    8月5日消息,據燈塔專業版數據,截至8月5日9時35分,8月總票房(含預售)已突破10億。其中,《封神》以大比分的優勢領先。根據官方消息,目前該片總票房已經超過14.
  • 2023 年的 Node.js 生態系統

    隨著技術的不斷演進和創新,Node.js 在 2023 年達到了一個新的高度。Node.js 擁有一個龐大的生態系統,可以幫助開發人員更快地實現復雜的應用。本文就來看看 Node.js 最新的生
  • CSS單標簽實現轉轉logo

    轉轉品牌升級后更新了全新的Logo,今天我們用純CSS來實現轉轉的新Logo,為了有一定的挑戰性,這里我們只使用一個標簽實現,將最大化的使用CSS能力完成Logo的繪制與動畫效果。新logo
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 網紅炒股不為了賺錢,那就是耍流氓!

    來源:首席商業評論6月26日高調宣布入市,網絡名嘴大v胡錫進居然進軍了股市。在一次財經媒體峰會上,幾個財經圈媒體大佬就&ldquo;胡錫進炒股是否知道認真報道&rdquo;展開討論。有
  • 攜眾多高端產品亮相ChinaJoy,小米帶來一場科技與人文的視聽盛宴

    7月28日,全球數字娛樂領域最具知名度與影響力的年度盛會中國國際數碼互動娛樂展覽會(簡稱ChinaJoy)在上海新國際博覽中心盛大開幕。作為全球領先的科
  • 三星折疊屏手機去年銷售近1000萬臺 今年目標定為1500萬

    7月29日消息,三星率先發力可折疊手機市場,在全球市場已經取得了非常亮眼的成績,接下來會進一步鞏固和擴大這一優勢。三星在推出Galaxy Z Flip5和Galax
  • 華為舉行春季智慧辦公新品發布會 首次推出電子墨水屏平板

    北京時間2月27日晚,華為在巴塞羅那舉行春季智慧辦公新品發布會,在海外市場推出之前已經在中國市場上市的筆記本、平板、激光打印機等辦公產品,并首次推出搭載
Top