91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

useEvent降低Hooks負擔的原生Hook分析

發布時間:2022-07-13 09:17:57 來源:億速云 閱讀:143 作者:iii 欄目:開發技術

這篇文章主要講解了“useEvent降低Hooks負擔的原生Hook分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“useEvent降低Hooks負擔的原生Hook分析”吧!

沒有 useEvent 的時候

我們先看看不用 useEvent 的情況:

function Chat() {
  const [text, setText] = useState('');
  // ???? Always a different function
  const onClick = () => {
    sendMessage(text);
  };
  return <SendButton onClick={onClick} />;
}

其中點擊事件的回調函數 onClick 中需要讀取當前鍵入的文本text,這里的onClick隨著組件重新渲染一次次地重新創建,每次都會是不一樣的引用,這顯然帶來了性能損耗,如果你想對其進行優化,你可能會這樣做:

function Chat() {
  const [text, setText] = useState('');
  // ???? A different function whenever `text` changes
  const onClick = useCallback(() => {
    sendMessage(text);
  }, [text]);
  return <SendButton onClick={onClick} />;
}

通過 useCallback 返回一個 memoized 回調函數。

useCallback: 返回一個 memoized 回調函數。 把內聯回調函數及依賴項數組作為參數傳入 useCallback,它將返回該回調函數的 memoized 版本,該回調函數僅在某個依賴項改變時才會更新。當你把回調函數傳遞給經過優化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子組件時,它將非常有用。 useCallback(fn, deps) 相當于 useMemo(() => fn, deps)

最終使得onClick的引用始終不變但是!

onClcik這個方法有需要保證每次都要拿到最新的、正確的text,所以他的deps中就自然是設置了text&mdash;&mdash; 壞了,“又回到最初的起點~”。隨著每一次keystrokeonClick又變成了上面的情況:

 Always a different function

但你又不能將其從deps中移除,移除了他就只能拿到text的初始值,失去了他本該有的功能...

小 useEvent 來給他整個活

useEvent就是為了解決此類問題,所以他干脆不要deps了,他就是一直返回一個相同的函數引用,哪怕text發生變化。當然,保證它也能拿到最新的、正確的**text**

function Chat() {
  const [text, setText] = useState('');
  // ? Always the same function (even if `text` changes)
  const onClick = useEvent(() => {
    sendMessage(text);
  });
  return <SendButton onClick={onClick} />;
}

現在好了:

  • onClick 的引用始終是同一個

  • 保證每次都能拿到最新的、正確的 text

當然還有其他一些場景,但是大致需求原理相同,就是不想讓A因為b變化而總是重新加載,但是又因為要拿到b恰當的值,所以deps中必須b,導致不得不重新加載,掉進了“圈圈圓圓圈圈~”的陷阱。更多場景這里就不再贅述。更多案例可查看文末的學習資源~

總而言之,用useEvent給他裹上就是香,就是可以同時達到上面兩個效果:

  • 引用不變

  • 拿到恰當的值

這是咋做到的????

說了這么多,我們來看看他這是咋做到的
大概是這么個形狀:(不是源碼就長這樣的意思嗷)

// (!) Approximate behavior
function useEvent(handler) {
  const handlerRef = useRef(null);
  // In a real implementation, this would run before layout effects
  useLayoutEffect(() => {
    handlerRef.current = handler;
  });
  return useCallback((...args) => {
    // In a real implementation, this would throw if called during render
    const fn = handlerRef.current;
    return fn(...args);
  }, []);
}

先回顧幾個Hook相關知識點:

useRef

useRef:

useRef 返回一個可變的 ref 對象,其 .current 屬性被初始化為傳入的參數(initialValue)。返回的 ref 對象在組件的整個生命周期內持續存在。

這里通過 useRef 保存回調函數handlerhandlerRef.current,然后再在 useCallback 中從handlerRef.current來取函數再調用,這樣避免了直接調用,跳出了閉包陷阱。并且不出意外的話handler在整個生命周期內持續存在,也就是只有一個引用

useLayoutEffect

這個 useLayoutEffect 可能沒那么常用,我們來看看這是啥嘞

其函數簽名與 useEffect 相同,但它會在所有的 DOM 變更之后同步調用 effect。可以使用它來讀取 DOM 布局并同步觸發重渲染。在瀏覽器執行繪制之前,useLayoutEffect 內部的更新計劃將被同步刷新。

useEffect

回顧一下 useEffect

默認情況下,effect 將在每輪渲染結束后執行

兩者的區別

好了,現在我給你用一個字總結一下兩者區別,useLayoutEffect 更“快”!這個“塊”不是速度更快,而是他“搶跑”了哩。useLayoutEffect 是在render之前同步執行,useEffectrender之后異步執行,這里就是保證useLayoutEffect 里的回調肯定比useEffect更早前被調用、被執行。

useCallback執行時機

前面說到

useCallback(fn, deps) 相當于 useMemo(() => fn, deps)

文檔里是這樣說 useMemo 的:

記住,傳入 useMemo 的函數會在渲染期間執行。請不要在這個函數內部執行與渲染無關的操作,諸如副作用這類的操作屬于 useEffect 的適用范疇,而不是 useMemo。

也就是他是在render執行的,也就是保證了賦值handlerhandlerRef.current是在前面發生

這里的作用

這里返回的是一個useCallback包裹后 memoized函數,其中從handlerRef.current中獲取函數,并且deps[],也就是說他不會再次更新。

感謝各位的閱讀,以上就是“useEvent降低Hooks負擔的原生Hook分析”的內容了,經過本文的學習后,相信大家對useEvent降低Hooks負擔的原生Hook分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

成都市| 祁阳县| 盐边县| 德格县| 瑞昌市| 江城| 兰西县| 深水埗区| 南京市| 临夏市| 泽州县| 武穴市| 方城县| 镇远县| 凤凰县| 临夏县| 墨脱县| 札达县| 合川市| 象州县| 新郑市| 阿拉善左旗| 齐河县| 盖州市| 皋兰县| 西乌| 鹤山市| 阿拉善右旗| 盐山县| 波密县| 金山区| 隆安县| 南投县| 宜兴市| 商洛市| 大连市| 竹山县| 邯郸市| 清丰县| 英吉沙县| 乌审旗|