成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

如何用ahooks控制時(shí)機(jī)的hook?

3403771864 / 514人閱讀

  本篇主要和大家溝通關(guān)于ahooks ,我們可以理解為加深對(duì) React hooks 的了解。

  我們先說(shuō)下關(guān)于抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫(kù)。

  其實(shí)我們應(yīng)該培養(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫(kù)是一個(gè)對(duì)源碼閱讀不錯(cuò)的選擇。

  注:本系列對(duì) ahooks 的源碼解析是基于v3.3.13。

  現(xiàn)在就進(jìn)入主題用ahooks 來(lái)封裝 React要注意的“時(shí)機(jī)”?

  Function Component VS Class Component

  很多時(shí)候代碼要講究先后順序,要掌握周期,且需知道在不同的階段執(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)單版如下所示:

1.png

  其中每個(gè)狀態(tài)中還會(huì)按順序調(diào)用不同的方法,直接看下圖:

2.png

  先要詳細(xì)了解,就去官網(wǎng)詳看??梢钥吹?,會(huì)有非常多的生命周期方法,而且在不同的版本,生命周期方法還不同。

  Function Component

  沒(méi)有生命周期的概念—Function Component ,它是更徹底的狀態(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ò)判斷有沒(méi)有執(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é)與思考

  寫代碼要清楚知道,組件的生命周期是怎樣的,還有代碼的執(zhí)行順序、執(zhí)行的時(shí)機(jī)是怎樣的。

  在 Function Component 中,使用 useEffect/useLayoutEffect 完成了 Class Components 生命周期的職責(zé)。ahooks 這就是的代碼執(zhí)行時(shí)機(jī),要是添加hook,就可以讓代碼具有可讀性以及邏輯更加清晰。



文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/128256.html

相關(guān)文章

  • ahooks正式發(fā)布React Hooks工具庫(kù)

      起因  社會(huì)在不斷的向前,技術(shù)也在不斷的完善進(jìn)步。從 React Hooks 正式發(fā)布到現(xiàn)在,越來(lái)越多的項(xiàng)目正在使用 Function Component 替代 Class Component,Hooks 這一新特性也逐漸被廣泛的使用。 這樣的解析是不是很熟悉,在日常中時(shí)常都有用到,但也有一個(gè)可以解決這樣重復(fù)的就是對(duì)數(shù)據(jù)請(qǐng)求的邏輯處理,對(duì)防抖節(jié)流的邏輯處理等。 另一方面,由于 Hoo...

    3403771864 評(píng)論0 收藏0
  • React官方團(tuán)隊(duì)實(shí)例原生Hook閉包陷阱

      陷進(jìn)到處都是?。”酒恼戮驼f(shuō)說(shuō)Hooks使用時(shí)存在所謂的閉包陷阱,看看下面代碼:  functionChat(){   const[text,setText]=useState('');   constonClick=useCallback(()=>{   sendMessage(text);   },[]);   return<SendButtononClick=...

    3403771864 評(píng)論0 收藏0
  • 解析ahooks整體架構(gòu)及React工具庫(kù)源碼

     這是講 ahooks 源碼的第一篇文章,簡(jiǎn)要就是以下幾點(diǎn):  加深對(duì) React hooks 的理解?! W(xué)習(xí)如何抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫(kù)。  培養(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫(kù)是一個(gè)對(duì)源碼閱讀不錯(cuò)的選擇?! ∽ⅲ罕鞠盗袑?duì) ahooks 的源碼解析是基于v3.3.13。自己 folk 了一份源碼,主要是對(duì)源碼做了一些解讀,可見詳情?! 〉谝黄饕榻B a...

    3403771864 評(píng)論0 收藏0
  • 詳解ahooks解決React閉包問(wèn)題方法

      想必大家都能看得懂的源碼 ahooks 整體架構(gòu)篇,且可以使用插件化機(jī)制優(yōu)雅的封裝你的請(qǐng)求hook,現(xiàn)在我們就探討下ahooks 是怎么解決 React 的閉包問(wèn)題的?。  React 的閉包問(wèn)題  先來(lái)看一個(gè)例子:  importReact,{useState,useEffect}from"react";   exportdefault()=>{   const[c...

    3403771864 評(píng)論0 收藏0
  • 關(guān)于ahooks封裝cookie localStorage sessionStorage方法

      之所以講這篇文章主要是為了加深對(duì) React hooks 的理解?! ∫虼?,先要學(xué)習(xí)如何抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫(kù)?! ∏遗囵B(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫(kù)是一個(gè)對(duì)源碼閱讀不錯(cuò)的選擇?! ‖F(xiàn)在看下ahooks 是怎么封裝 cookie/localStorage/sessionStorage 的?! ookie  ahooks 封裝了 useCookie...

    3403771864 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<