精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

useEffect 實(shí)踐案例:自定義 Hook

開發(fā) 前端
我們常常會封裝一個(gè)函數(shù)用于邏輯的復(fù)用。自定義 Hook 也是這樣的一個(gè)在 React 組件內(nèi)部用于邏輯復(fù)用的函數(shù)封裝。

我們將在上一章案例的基礎(chǔ)之上學(xué)習(xí)自定義 hook。

上一章中,我們巧妙的把大量的 JSX 邏輯處理封裝在了 List 組件中,使得在頁面組件的代碼變得非常簡單。這是針對 UI 層的邏輯處理,那么在數(shù)據(jù)的處理上,是否也能夠進(jìn)行一些封裝呢?

// 數(shù)據(jù)的主要核心邏輯
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)
}

答案是肯定的,解決方案就是我們將要在本章中學(xué)習(xí)的自定義 hook。

一、自定義hook

我們常常會封裝一個(gè)函數(shù)用于邏輯的復(fù)用。自定義 hook 也是這樣的一個(gè)在 react 組件內(nèi)部用于邏輯復(fù)用的函數(shù)封裝。

和普通函數(shù)封裝相比,他唯一的特殊之處就在于我們常常會將 react 內(nèi)置 hook 封裝在邏輯之中,比如 useState,useEffect 等。除此之外,為了區(qū)分與普通的函數(shù)封裝,我們必須以 use 開頭為自定義 hook 命名,這樣的 hook 只能在 React 組件中使用。

以上一章中的數(shù)據(jù)處理邏輯為例,我們來封裝一個(gè)自定義 hook,將其命名為 useFetch。

function useFetch() {}

我們先考慮單個(gè)場景的封裝,單純只是為了讓組件看上去更簡潔。

我們就可以把所有的數(shù)據(jù)和處理數(shù)據(jù)的邏輯封裝起來。

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 }
}

封裝過程非常簡單,就是把之前那一堆邏輯全部遷移過來,最后返回應(yīng)用組件里需要的數(shù)據(jù)和方法即可。

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

OK,此時(shí)我們來觀察一下組件里的代碼。

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="請輸入您要搜索的內(nèi)容"
          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>
  )
}

邏輯簡潔了許多。變成了簡單的同步代碼:通過一個(gè)方法獲取數(shù)據(jù),并將數(shù)據(jù)渲染到 UI 組件。

Block 組件是單獨(dú)封裝的布局組件,希望不要因此造成任何理解上的困難。

一個(gè)組件變成了數(shù)據(jù)與UI的結(jié)合。我們分別將復(fù)雜的數(shù)據(jù)處理邏輯封裝在 hook 里,將復(fù)雜的UI交互邏輯封裝在基礎(chǔ) UI 組件里,在使用時(shí),利用他們的封裝結(jié)果進(jìn)行組合,能夠簡單,高效的組合出復(fù)雜的頁面,這也是我們在實(shí)踐中最大的追求

這里有些人可能會有一些疑問,我只是把一些邏輯放在了另外的地方,代碼量最終不僅沒有減少,反而還變多了,這樣做的好處真的有那么大嗎?當(dāng)然,因?yàn)槲覀兎庋b的 useFetch 和 List 組件,他們承載了大多數(shù)的復(fù)雜邏輯,并且只會在最開始的時(shí)候編寫一次,在以后的使用中,就直接引入使用就行了,這極大的簡化了后續(xù)的開發(fā)工作量,對工作效率的提高非常顯著

二、進(jìn)一步思考

此時(shí)的封裝雖然足夠簡潔。但是沒有考慮復(fù)用。因此還需要進(jìn)一步思考改進(jìn)。

我們來分析一下場景:每一個(gè)需要信息展示的頁面,基本邏輯都是在初始化時(shí),請求接口,獲得數(shù)據(jù),然后展示信息。我們可以把不同情況的接口請求抽象成為一個(gè)接口,然后基于這個(gè)場景來思考不同頁面的請求的共性與差異。

每個(gè)頁面都要處理信息展示、異常等邏輯,差異的地方就在于獲取數(shù)據(jù)的 api 函數(shù)不一樣,他返回的數(shù)據(jù)內(nèi)容,數(shù)據(jù)類型也不一樣。

不一樣的東西作為參數(shù)傳入,那我們只需要將 api 函數(shù)作為參數(shù)傳入即可。

const info = useFetch(searchApi)

不過我們此時(shí)還需要考慮的是,為了確保自定義 hook 的返回類型具備完整準(zhǔn)確的類型推導(dǎo),我們還需要約定傳入 api 的參數(shù)類型與返回類型。

因此,在定義 useFetch 時(shí),我們先用 ts 約定 api 的具體類型,因?yàn)閰?shù)類型和返回值類型在封裝時(shí)都不確定,只能在具體的實(shí)參傳入之后才能明確,因此使用兩個(gè)泛型來分別表示參數(shù)類型和返回值類型。

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

正常代碼不會這樣換行,之所以這樣只是為了在移動端能夠更多的展示代碼信息而不用滾動查看。

然后在定義 useFetch 時(shí)傳入這兩個(gè)泛型即可,完整代碼如下:

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 
  }
}

因?yàn)樵谑褂脮r(shí),傳入的 api 函數(shù)已經(jīng)具備了完善的類型,因此我們這種寫法可以借助 ts 內(nèi)部的自動推導(dǎo)而簡化使用時(shí)在 ts 上的繁瑣。

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

雖然在使用層面沒有任何 ts 的痕跡,但是返回值的類型已經(jīng)非常明確。

由于在封裝過程中我們沒有處理默認(rèn)值的情況,因此返回類型可能為 undefined,這在實(shí)踐中一定要引起重視。你可以根據(jù)實(shí)際情況往 useFetch 傳入默認(rèn)值,也可以在使用層面初始化默認(rèn)值

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

這樣,一個(gè)通用,高效,且具備準(zhǔn)確類型提示的 hook 就被我們封裝好了。

在實(shí)踐過程中,由于不同的團(tuán)隊(duì)有不同的需求,你還需要根據(jù)自己的需求和項(xiàng)目實(shí)際情況做相應(yīng)的細(xì)節(jié)調(diào)整,切記不要完整套用。

三、取舍

由于面試的影響,讓不少前端同行錯(cuò)誤的把性能當(dāng)成了實(shí)踐中最重要的標(biāo)準(zhǔn)。但其實(shí)工作中性能并不是最高的優(yōu)先級。我們往往會在可接受的范圍之內(nèi),犧牲性能換取其他的便利。

例如,多一層函數(shù)封裝,其實(shí)也就意味著執(zhí)行壓力多那么一點(diǎn)點(diǎn)。但是他可能換來的是開發(fā)效率的極大提高。

因此,在我們的課程案例決策當(dāng)中,提供的方案并不會把性能當(dāng)做第一準(zhǔn)則,代碼的可讀性、可維護(hù)性、開發(fā)效率的優(yōu)先級都會比性能更高。只要我們在寫代碼的過程中,非常明確的知道這種方式我們舍棄了什么,得到了什么,你權(quán)衡之后,愿意做出這樣的取舍,那么這樣的方式就是可以使用的。

當(dāng)然,性能依然非常重要,如果你的頁面出現(xiàn)了卡頓,我們就應(yīng)該思考一下,是不是對性能的犧牲有點(diǎn)過了頭。

責(zé)任編輯:姜華 來源: 這波能反殺
相關(guān)推薦

2023-11-30 07:45:11

useEffectReact

2017-05-18 12:36:16

android萬能適配器列表視圖

2017-05-19 10:03:31

AndroidBaseAdapter實(shí)踐

2022-06-06 09:28:36

ReactHook

2025-01-22 11:10:34

2021-02-23 08:01:01

HooksReact架構(gòu)

2023-09-27 22:10:47

Vue.jsJavaScript

2025-05-15 07:11:51

2010-08-12 09:45:33

jQuery自定義事件

2023-06-27 15:02:47

2023-06-28 08:05:46

場景vue3自定義

2015-02-12 15:33:43

微信SDK

2015-02-12 15:38:26

微信SDK

2016-11-16 21:55:55

源碼分析自定義view androi

2016-12-26 15:25:59

Android自定義View

2024-06-13 09:50:45

2011-06-23 10:49:13

Qt 自定義信號

2016-02-26 14:57:50

飛象網(wǎng)

2009-07-06 16:59:26

JSP自定義標(biāo)簽

2013-06-27 11:10:01

iOS開發(fā)自定義UISlider
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

91欧美视频网站| 3751色影院一区二区三区| 久草精品电影| 国产亚洲欧美日韩高清| 日韩精品久久| 91麻豆精品国产91久久久资源速度| 亚洲精品偷拍视频| 少妇高潮一区二区三区99小说 | 色视频一区二区三区| 自拍偷拍第八页| 亚洲私拍自拍| 深夜福利一区二区| 中文字幕99页| 欧美日韩视频免费看| 亚洲国产欧美在线人成| 日韩国产欧美精品| 亚洲国产精品久久人人爱潘金莲| 三级成人在线视频| 久久免费视频观看| 亚洲av熟女国产一区二区性色| 欧美视频二区欧美影视| 日韩欧美在线观看| www.男人天堂网| av网站大全在线观看| 高清国产一区二区| 国产精品一区二区电影| 日本网站在线播放| 综合天堂av久久久久久久| 亚洲欧洲日产国码av系列天堂| www.欧美激情.com| 国产精品扒开腿做爽爽爽视频软件| 尤物av一区二区| 亚洲国产精品一区二区第一页 | 亚洲视屏在线播放| 精品国产免费久久久久久婷婷| 九七影院97影院理论片久久| 欧美性色视频在线| 精品久久一二三| 超碰porn在线| 国产精品免费网站在线观看| 久久影院理伦片| 欧美一级淫片免费视频魅影视频| 韩国三级中文字幕hd久久精品| 国产成人高潮免费观看精品| 国产精品suv一区二区69| 欧美va天堂在线| 日韩在线www| 91精品久久久久久久久久久久| 亚州国产精品| 日韩精品福利在线| 国模无码视频一区| 国产精品色呦| 亚洲成人av在线播放| 又黄又色的网站| 亚洲欧美日本国产| 欧美变态凌虐bdsm| 乱码一区二区三区| 狼人天天伊人久久| 亚洲国产精品推荐| 99久久人妻无码中文字幕系列| 91成人午夜| 欧美网站大全在线观看| 99视频在线免费| 99久久亚洲国产日韩美女| 在线观看视频一区| 精品999在线| 四虎影视成人精品国库在线观看| 欧美日韩精品电影| 亚洲欧美日韩综合网| 日韩专区视频| 日韩欧美一区二区视频| 性活交片大全免费看| 国产+成+人+亚洲欧洲在线| 精品国内二区三区| 国产黑丝一区二区| 久草在线成人| 中文字幕在线视频日韩| 一区二区成人免费视频| 欧美精品一卡| 国内外成人免费激情在线视频| 日韩美女一级片| 久久国产免费| 国产精品一区二区电影| 国产黄色av网站| 99久久久精品| 爽爽爽在线观看| 久久精品国产亚洲a∨麻豆| 成人丝袜18视频在线观看| 国产精品国产精品国产专区不卡| 黄色三级网站在线观看| 91老师片黄在线观看| 色女人综合av| 日本资源在线| 欧美性色19p| www.国产视频.com| 国产精品毛片久久久| 亚洲人午夜精品免费| 亚洲区一区二区三| 亚洲国产裸拍裸体视频在线观看乱了中文 | 最新天堂中文在线| 精品国模一区二区三区欧美| 亚洲精品一区二区三区婷婷月| 国产调教在线观看| 亚洲小说欧美另类社区| 国产精品成熟老女人| av中文字幕免费| 久久久国产精华| 日本aa在线观看| 影音成人av| 亚洲成人精品视频在线观看| 久久福利视频网| 玩弄japan白嫩少妇hd| 亚洲一区二区av| 亚洲国产欧美一区二区三区同亚洲| 99精品全国免费观看| 亚洲日本视频| 国产在线观看不卡| 视频福利在线| 亚洲夂夂婷婷色拍ww47| 色免费在线视频| 首页亚洲中字| 久久高清视频免费| 亚洲视频在线观看一区二区| 91在线一区二区| 免费的av在线| 成人午夜在线| 亚洲人成电影网站色xx| 国产精品99精品| 国产精品伊人色| 亚洲黄色成人久久久| 老色鬼在线视频| 欧美成人一区二区三区| 午夜国产福利视频| 日日夜夜精品视频免费| 国语精品中文字幕| 婷婷色在线播放| 在线播放91灌醉迷j高跟美女| 欧美大波大乳巨大乳| 亚洲一区国产一区| 国产精品国产三级欧美二区| www红色一片_亚洲成a人片在线观看_| 欧美日韩在线播放三区| 色一情一交一乱一区二区三区| 一区二区三区四区五区精品视频| 成人自拍网站| 免费电影网站在线视频观看福利| 777午夜精品视频在线播放| 国产一级aa大片毛片| 国内精彩免费自拍视频在线观看网址| 欧美日韩精品一区视频| 四虎影成人精品a片| 亚洲狼人精品一区二区三区| 91入口在线观看| 黄页视频在线播放| 欧美日韩国产精品成人| www..com.cn蕾丝视频在线观看免费版| 宅男噜噜噜66国产日韩在线观看| 99久久国产免费免费| 黄色网页在线看| 91麻豆精品国产自产在线| 久久国产波多野结衣| 国产乱码一区二区三区| 欧美日韩午夜爽爽| 亚洲综合色婷婷在线观看| 欧美国产第一页| 亚洲精品久久久久久动漫器材一区| 一区二区三区四区在线免费观看| 国产xxx在线观看| 黄色成人精品网站| 国产另类自拍| 小草在线视频免费播放| 国产亚洲精品一区二555| a片在线免费观看| 日韩一区有码在线| 麻豆精品国产传媒| 亚洲经典自拍| 欧美在线3区| 久久日本片精品aaaaa国产| 久久久99免费视频| 狠狠躁日日躁夜夜躁av| 欧美日韩视频免费播放| 国产成人免费观看网站| 激情综合网天天干| 国产夫妻自拍一区| 蜜臀av免费一区二区三区| 国产精品视频免费在线| 羞羞的视频在线看| 亚洲精品一区二区久| 亚洲图片中文字幕| 91精品美女| 欧美v亚洲v综合ⅴ国产v| 日本一级黄色录像| 国产亚洲综合av| 色男人天堂av| 国产精品情侣呻吟对白视频| 久久久一二三| 好吊色视频988gao在线观看| 欧美日韩一本| 国产日韩欧美日韩| 成人影音在线| 国产一区二区免费| 不卡的日韩av| 在线视频国内自拍亚洲视频| 日韩女优一区二区| 久久久久亚洲av片无码| 国产欧美亚洲精品a| 在线精品国精品国产尤物884a| 呻吟揉丰满对白91乃国产区| 懂色av一区二区夜夜嗨| 国产裸体免费无遮挡| 欧美日一区二区在线观看 | 91国内精品久久久| 亚洲成av人片| 精品无码一区二区三区蜜臀| 97精品视频在线观看自产线路二| 日韩精品视频一二三| 免费中文字幕日韩欧美| 国产91沈先生在线播放| 久久伦理在线| 欧美精品在线一区| 99re8这里有精品热视频8在线| 91精品国产综合久久久久久久久| 一个人看的www视频在线免费观看 一个人www视频在线免费观看 | 97人人模人人爽人人喊中文字 | 天天爽夜夜爽一区二区三区| 国产婷婷精品| 性高湖久久久久久久久aaaaa| 久久精品高清| 日韩电影天堂视频一区二区| 国产精品高潮呻吟久久久久| 91欧美精品午夜性色福利在线 | 在线观看视频一区二区欧美日韩| 国产精彩视频在线| 亚洲精品网站在线观看| 亚洲国产精品一区二区久久hs| 久久综合狠狠综合久久激情| 无码人妻一区二区三区精品视频| 麻豆国产精品官网| 别急慢慢来1978如如2| 国产精品永久| 欧美日韩性生活片| 亚洲三级网站| 欧美午夜性视频| 在线精品视频在线观看高清| 欧美性天天影院| 国产精品毛片av| 成人久久18免费网站漫画| 国产精品色婷婷在线观看| 成人xxxx视频| 婷婷激情成人| 国产美女被下药99| 玖玖精品在线| 成人国产精品色哟哟| 亚洲国产精选| 91在线精品视频| 精品一区二区三区在线观看视频| 国产伊人精品在线| 亚洲国产伊人| 99re视频在线观看| 综合欧美亚洲| 国产一区二区三区av在线| 久久久久久毛片免费看| 精品久久久久亚洲| 久草成人资源| 日韩亚洲视频在线| 日本一区二区在线看| 亚洲欧洲精品在线| 91精品啪在线观看国产81旧版| 熟女视频一区二区三区| 狠狠噜噜久久| 中国丰满人妻videoshd| 日韩激情在线观看| 亚洲天堂国产视频| 国产精品一区二区在线播放 | 久久久91精品国产一区二区三区| 亚洲成人网在线播放| 欧美韩国日本综合| 亚洲天堂网av在线| 洋洋成人永久网站入口| 在线观看黄网站| 精品视频色一区| 国产高清在线观看视频| 亚洲国产日韩欧美在线动漫| 经典三级在线| 久久久999国产| 岛国av免费在线观看| 国产精品成人一区二区| 日韩精品一区国产| 久久伊人一区| 亚洲欧美综合久久久| 波多野结衣家庭教师在线播放| 日本欧美一区二区在线观看| 亚洲自拍第三页| 96av麻豆蜜桃一区二区| 日韩在线不卡av| 亚洲成a人片在线不卡一二三区| 天天爽夜夜爽人人爽| 91精品久久久久久蜜臀| 亚洲区小说区图片区| 日韩中文字幕网| 国产粉嫩在线观看| 成人免费视频在线观看超级碰| 国产精品宾馆| 中国一级黄色录像| 午夜亚洲视频| 成人高清在线观看视频| 久久久一区二区| avtt天堂在线| 欧洲国产伦久久久久久久| 丰满人妻一区二区三区免费视频| 亚洲丝袜一区在线| 日本精品600av| 国产精品影片在线观看| 另类ts人妖一区二区三区| 久久av秘一区二区三区| 久久一日本道色综合久久| 特种兵之深入敌后| 国产精品女主播在线观看| 国产黄色片免费看| 日韩一级黄色片| 亚洲搞黄视频| 国产99久久精品一区二区永久免费| 亚洲网一区二区三区| 亚洲一区二区三区午夜| 媚黑女一区二区| 日本一区二区在线免费观看| 一区二区三区四区在线免费观看| 亚洲熟女乱色一区二区三区久久久| 日韩精品www| av毛片午夜不卡高**水| 2020国产精品久久精品不卡| 欧美va久久久噜噜噜久久| 久久久久久久久久久久久国产精品| 成人综合在线观看| 男人的天堂久久久| 欧美精品日韩精品| 无遮挡动作视频在线观看免费入口 | 久久av免费观看| 亚洲美女网站| 无码国产精品一区二区免费式直播| 中文字幕日韩一区二区| 中文字幕永久免费视频| 国产亚洲xxx| 三级成人黄色影院| 欧美日韩一区二区视频在线 | 51精品在线观看| 黄色美女久久久| 精品少妇人妻av免费久久洗澡| 国产**成人网毛片九色| 亚洲一区二区91| 亚洲精品一区二区精华| av在线加勒比| 精品一区二区视频| 亚洲欧美视频一区二区三区| 实拍女处破www免费看| 色综合天天性综合| 国产天堂素人系列在线视频| 国产精品电影在线观看| 第一会所sis001亚洲| 91国内在线播放| 亚洲激情中文1区| 亚洲乱码精品久久久久..| 欧美精品久久久久| 美女呻吟一区| 99免费视频观看| 中文乱码免费一区二区| 国产又大又长又粗| 欧美大肥婆大肥bbbbb| 成人福利免费在线观看| 亚洲国产精品久久久久婷蜜芽| 91网站黄www| 最近中文字幕av| 欧美成人小视频| 国内自拍欧美| 妞干网在线免费视频| 国产精品国产三级国产三级人妇 | 亚洲欧洲在线看| 国产精品无码久久久久| 永久免费在线看片视频| 99视频精品在线| 国产偷人爽久久久久久老妇app | 国产免费拔擦拔擦8x高清在线人| 精品一卡二卡三卡四卡日本乱码 | 色综合天天综合网国产成人综合天 | 成人四虎影院| 国产1区2区3区中文字幕| 久久综合色8888| 国产又粗又猛又爽又黄91| 久久久久久97| 欧美日韩激情| 亚洲av无码久久精品色欲| 一本色道**综合亚洲精品蜜桃冫| 欧美jizz18hd性欧美| 国产偷国产偷亚洲高清97cao| 老妇喷水一区二区三区| 欧美性猛交xxxxx少妇| 亚洲毛片在线看| 国产精品一区二区精品| 成人一级片网站| 亚洲欧美aⅴ...|