亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法

 更新時(shí)間:2022年07月11日 15:03:42   作者:Gopal  
這篇文章主要為大家介紹了ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

本文是深入淺出 ahooks 源碼系列文章的第五篇,這個(gè)系列的目標(biāo)主要有以下幾點(diǎn):

  • 加深對(duì) React hooks 的理解。
  • 學(xué)習(xí)如何抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫(kù)。
  • 培養(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫(kù)是一個(gè)對(duì)源碼閱讀不錯(cuò)的選擇。

注:本系列對(duì) ahooks 的源碼解析是基于 v3.3.13。自己 folk 了一份源碼,主要是對(duì)源碼做了一些解讀,可見 詳情。

本文來(lái)探索一下 ahooks 是怎么封裝 React 的一些執(zhí)行“時(shí)機(jī)”的?

Function Component VS Class Component

學(xué)習(xí)類似 React 和 Vue 這種框架,對(duì)它們生命周期的掌握都是必須的,我們需要清楚的知道我們代碼的執(zhí)行順序,并且在不同的階段執(zhí)行不同操作的代碼,比如需要掛載完成之后才去獲取 dom 的值,否則可能會(huì)獲取不到相應(yīng)的值。

Class Component

使用過(guò) React 的 Class Component 的同學(xué),就會(huì)知道其組件生命周期會(huì)分成三個(gè)狀態(tài):

  • Mounting(掛載):已插入真實(shí) DOM
  • Updating(更新):正在被重新渲染
  • Unmounting(卸載):已移出真實(shí) DOM

簡(jiǎn)單版如下所示:

其中每個(gè)狀態(tài)中還會(huì)按順序調(diào)用不同的方法,對(duì)應(yīng)的詳細(xì)如下(這里不展開說(shuō)):

可以通過(guò)官方提供這個(gè)網(wǎng)站查看詳情

可以看到,會(huì)有非常多的生命周期方法,而且在不同的版本,生命周期方法還不同。

Function Component

到了 Function Component ,會(huì)發(fā)現(xiàn)沒有直接提及生命周期的概念,它是更徹底的狀態(tài)驅(qū)動(dòng),它只有一個(gè)狀態(tài),React 負(fù)責(zé)將狀態(tài)渲染到視圖中。

對(duì)于 Function Component 來(lái)說(shuō)由狀態(tài)到頁(yè)面渲染只有三步:

  • 輸入狀態(tài)(prop、state)
  • 執(zhí)行組件的邏輯,并在 useEffect/useLayoutEffect 中訂閱副作用
  • 輸出UI(Dom節(jié)點(diǎn))

重點(diǎn)是第二步,React 通過(guò) useEffect/useLayoutEffect 訂閱副作用。Class Component 中的生命周期都可以通過(guò) useEffect/useLayoutEffect 來(lái)實(shí)現(xiàn)。它們兩個(gè)的功能非常相似,我們這里看下 useEffect。

使用 useEffect 相當(dāng)于告訴 React 組件需要在渲染后執(zhí)行某些操作,React 將在執(zhí)行 DOM 更新之后調(diào)用它。React 保證了每次運(yùn)行 useEffect 的時(shí)候,DOM 已經(jīng)更新完畢。這就實(shí)現(xiàn)了 Class Component 中的 Mounting(掛載階段)。

當(dāng)狀態(tài)發(fā)生變化的時(shí)候,它能夠執(zhí)行對(duì)應(yīng)的邏輯、更行狀態(tài)并將結(jié)果渲染到視圖中,這就完成了 Class Component 中的 Updating(更新階段)。

最后通過(guò)在 useEffect 中返回一個(gè)函數(shù),它便可以清理副作用。它的規(guī)則是:

  • 首次渲染不會(huì)進(jìn)行清理,會(huì)在下一次渲染,清除上一次的副作用。
  • 卸載階段也會(huì)執(zhí)行清除操作。

通過(guò)返回一個(gè)函數(shù),我們就能實(shí)現(xiàn) Class Component 中的 Unmounting(卸載階段)。

基于 useEffect/useLayoutEffect,ahooks 做了一些封裝,能夠讓你更加清晰的知道你的代碼執(zhí)行時(shí)機(jī)。

LifeCycle - 生命周期

useMount

只在組件初始化時(shí)執(zhí)行的 Hook。 useEffect 依賴假如為空,只會(huì)在組件初始化的時(shí)候執(zhí)行。

// 省略部分代碼
const useMount = (fn: () => void) => {
  // 省略部分代碼
  // 單純就在 useEffect 基礎(chǔ)上封裝了一層
  useEffect(() => {
    fn?.();
  }, []);
};
export default useMount;

useUnmount

useUnmount,組件卸載(unmount)時(shí)執(zhí)行的 Hook。

useEffect 可以在組件渲染后實(shí)現(xiàn)各種不同的副作用。有些副作用可能需要清除,所以需要返回一個(gè)函數(shù),這個(gè)函數(shù)會(huì)在組件卸載的時(shí)候執(zhí)行。

const useUnmount = (fn: () => void) => {
  const fnRef = useLatest(fn);
  useEffect(
    // 在組件卸載(unmount)時(shí)執(zhí)行的 Hook。
    // useEffect 的返回值中執(zhí)行函數(shù)
    () => () => {
      fnRef.current();
    },
    [],
  );
};
export default useUnmount;

useUnmountedRef

獲取當(dāng)前組件是否已經(jīng)卸載的 Hook。

通過(guò)判斷有沒有執(zhí)行 useEffect 中的返回值判斷當(dāng)前組件是否已經(jīng)卸載。

// 獲取當(dāng)前組件是否已經(jīng)卸載的 Hook。
const useUnmountedRef = () => {
  const unmountedRef = useRef(false);
  useEffect(() => {
    unmountedRef.current = false;
    // 如果已經(jīng)卸載,則會(huì)執(zhí)行 return 中的邏輯
    return () => {
      unmountedRef.current = true;
    };
  }, []);
  return unmountedRef;
};
export default useUnmountedRef;

Effect

這里只會(huì)講官方文檔 Effect 下面的幾個(gè),有部分是定時(shí)器、防抖節(jié)流等,咱們后面的系列具體分析。

useUpdateEffect 和 useUpdateLayoutEffect

useUpdateEffect 和 useUpdateLayoutEffect 的用法跟 useEffect 和 useLayoutEffect 一樣,只是會(huì)忽略首次執(zhí)行,只在依賴更新時(shí)執(zhí)行。

實(shí)現(xiàn)思路:初始化一個(gè)標(biāo)識(shí)符,剛開始為 false。當(dāng)首次執(zhí)行完的時(shí)候,置為 true。只有標(biāo)識(shí)符為 true 的時(shí)候,才執(zhí)行回調(diào)函數(shù)。

// 忽略首次執(zhí)行
export const createUpdateEffect: (hook: effectHookType) => effectHookType =
  (hook) => (effect, deps) => {
    const isMounted = useRef(false);
    // for react-refresh
    hook(() => {
      return () => {
        isMounted.current = false;
      };
    }, []);
    hook(() => {
      // 首次執(zhí)行完時(shí)候,設(shè)置為 true,從而下次依賴更新的時(shí)候可以執(zhí)行邏輯
      if (!isMounted.current) {
        isMounted.current = true;
      } else {
        return effect();
      }
    }, deps);
  };

useDeepCompareEffect和useDeepCompareLayoutEffect

用法與 useEffect 一致,但 deps 通過(guò) lodash isEqual 進(jìn)行深比較。

通過(guò) useRef 保存上一次的依賴的值,跟當(dāng)前的依賴對(duì)比(使用 lodash 的 isEqual),并將對(duì)比結(jié)果作為 useEffect 的依賴項(xiàng),從而決定回調(diào)函數(shù)是否執(zhí)行。

const depsEqual = (aDeps: DependencyList, bDeps: DependencyList = []) => {
  return isEqual(aDeps, bDeps);
};
const useDeepCompareEffect = (effect: EffectCallback, deps: DependencyList) => {
  // 通過(guò) useRef 保存上一次的依賴的值
  const ref = useRef<DependencyList>();
  const signalRef = useRef<number>(0);
  // 判斷最新的依賴和舊的區(qū)別
  // 如果相等,則變更 signalRef.current,從而觸發(fā) useEffect 中的回調(diào)
  if (!depsEqual(deps, ref.current)) {
    ref.current = deps;
    signalRef.current += 1;
  }
  useEffect(effect, [signalRef.current]);
};

useUpdate

useUpdate 會(huì)返回一個(gè)函數(shù),調(diào)用該函數(shù)會(huì)強(qiáng)制組件重新渲染。

返回的函數(shù)通過(guò)變更 useState 返回的 state,從而促使組件進(jìn)行更新。

import { useCallback, useState } from 'react';
const useUpdate = () => {
  const [, setState] = useState({});
  // 通過(guò)設(shè)置一個(gè)全新的狀態(tài),促使 function 組件更新
  return useCallback(() => setState({}), []);
};
export default useUpdate;

總結(jié)與思考

在我們寫代碼的時(shí)候需要清晰的知道,組件的生命周期是怎樣的,我們代碼的執(zhí)行順序、執(zhí)行的時(shí)機(jī)是怎樣的。

在 Function Component 中,使用 useEffect/useLayoutEffect 完成了 Class Components 生命周期的職責(zé)。ahooks 也是基于這兩個(gè)封裝了常見的代碼執(zhí)行時(shí)機(jī),使用這些 hook,可以讓我們的代碼更加具有可讀性以及邏輯更加清晰。

以上就是ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于ahooks控制時(shí)機(jī)hook的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React?Hooks--useEffect代替常用生命周期函數(shù)方式

    React?Hooks--useEffect代替常用生命周期函數(shù)方式

    這篇文章主要介紹了React?Hooks--useEffect代替常用生命周期函數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • React-hooks中的useEffect使用步驟

    React-hooks中的useEffect使用步驟

    這篇文章主要介紹了React-hooks中的useEffect,對(duì)于React組件來(lái)說(shuō),主作用是根據(jù)數(shù)據(jù)(state/props)渲染UI,除此之外都是副作用(比如手動(dòng)修改DOM、發(fā)送ajax請(qǐng)求),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-05-05
  • react-native 實(shí)現(xiàn)漸變色背景過(guò)程

    react-native 實(shí)現(xiàn)漸變色背景過(guò)程

    這篇文章主要介紹了react-native 實(shí)現(xiàn)漸變色背景過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • React Native項(xiàng)目框架搭建的一些心得體會(huì)

    React Native項(xiàng)目框架搭建的一些心得體會(huì)

    React Native使你能夠在Javascript和React的基礎(chǔ)上獲得完全一致的開發(fā)體驗(yàn),構(gòu)建世界一流的原生APP。接下來(lái)通過(guò)本文給大家分享React Native項(xiàng)目框架搭建的一些心得體會(huì),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • React組件內(nèi)事件傳參實(shí)現(xiàn)tab切換的示例代碼

    React組件內(nèi)事件傳參實(shí)現(xiàn)tab切換的示例代碼

    本篇文章主要介紹了React組件內(nèi)事件傳參實(shí)現(xiàn)tab切換的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • React路由渲染方式與withRouter高階組件及自定義導(dǎo)航組件應(yīng)用詳細(xì)介紹

    React路由渲染方式與withRouter高階組件及自定義導(dǎo)航組件應(yīng)用詳細(xì)介紹

    這篇文章主要介紹了React路由三種渲染方式、withRouter高階組件、自定義導(dǎo)航組件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • React?Hooks使用startTransition與useTransition教程示例

    React?Hooks使用startTransition與useTransition教程示例

    這篇文章主要為大家介紹了React?Hooks使用startTransition與useTransition教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React中常見的動(dòng)畫實(shí)現(xiàn)的幾種方式

    React中常見的動(dòng)畫實(shí)現(xiàn)的幾種方式

    本篇文章主要介紹了React中常見的動(dòng)畫實(shí)現(xiàn)的幾種方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • React深入了解原理

    React深入了解原理

    React是用于構(gòu)建用戶界面的JavaScript庫(kù),?[1]??起源于Facebook的內(nèi)部項(xiàng)目,該公司對(duì)市場(chǎng)上所有?JavaScript?MVC框架都不滿意,決定自行開發(fā)一套,用于架設(shè)Instagram的網(wǎng)站
    2022-07-07
  • 一篇文章教你用React實(shí)現(xiàn)菜譜系統(tǒng)

    一篇文章教你用React實(shí)現(xiàn)菜譜系統(tǒng)

    本篇文章主要介紹了React實(shí)現(xiàn)菜譜軟件的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-09-09

最新評(píng)論