簡體   English   中英

在沒有 React.memo 的情況下使用 useCallback 有什么好處嗎?

[英]is there any benefit of using useCallback without React.memo?

從我從 React 文檔和網絡上的其他材料中了解到,useCallback 用於通過確保將回調的記憶版本傳遞給子組件來避免重新渲染子組件,因此子組件的引用 props 保持不變。 但這一切僅在我在子組件上使用 React.memo 時才有效。 沒有 React.memo,子組件無論如何都會重新渲染。 我的問題是在這種情況下 useCallback 有什么用,即沒有將 React.memo 應用於子組件。 useCallback 的其他好處是什么?

React.memo 確保在 props 進入組件時執行淺比較,並在它們相等時跳過組件的渲染。

給定一個子組件 Cell:當應用於在渲染另一個父組件期間創建的功能組件時,將在每次渲染時創建一個新的 Cell 組件。 這個新的 Cell 組件將始終對其 props 進行淺層比較,但它會在每次渲染其父級時重新渲染。

但是,如果它的依賴數組在父重新渲染期間沒有更改,則 useCallback 將記住此函數回調 Cell。 單獨一個包含在 useCallback 中的函數組件 Cell 在接收到 props 時將始終重新渲染,這將在其父級的每次渲染中發生。 然而不同的是,如果組件本身被重新創建,它的整個子樹會被重新渲染,就像單獨使用 React.memo 時的情況一樣。

然而,配對在一起,您可以繞過重新渲染在父級內部定義的組件。

您會注意到,當嘗試拖動 Memoized 單元格時,未包含在 useCallback 中的單元格不會發生拖動。 這是因為當它的父元素重新渲染時,您嘗試拖動的原始元素被重新創建為新實例。 這個概念在這里有更詳細的解釋

例子

 const { useCallback, useState, useRef } = React; function App() { const [state, setState] = useState(false); const [title, setTitle] = useState(""); const Cell = useCallback(({ title }) => { console.log(`${title} rendering`); function onDragStart() { setState(true); } function onDragEnd() { setState(false); } return ( <div draggable onDragStart={onDragStart} onDragEnd={onDragEnd}> Drag {title} </div> ); }, []); const MemoizedCell = React.memo(({ title }) => { console.log(`${title} rendering`); function onDragStart() { setState(true); } function onDragEnd() { setState(false); } return ( <div draggable onDragStart={onDragStart} onDragEnd={onDragEnd}> Drag {title} </div> ); }); const MemoizedCallbackCell = useCallback( React.memo(({ title }) => { console.log(`${title} rendering`); function onDragStart() { setState(true); } function onDragEnd() { setState(false); } return ( <div draggable onDragStart={onDragStart} onDragEnd={onDragEnd}> Drag {title} <button onClick={() => setTitle(" Updated")}>Change Title</button> </div> ); }), [] ); return ( <div className="App"> <Cell title="Cell" /> <MemoizedCell title="Memoized Cell" /> <MemoizedCallbackCell title={"Memoized Callback Cell" + title} /> Is dragging {`${state}`} <br /> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));

您可能還需要將函數傳遞給useEffect而不在每次渲染時更改useEffect

例如:

import { useCallback, useEffect } from "react";

function useExample() {
  function fn() {
    console.log("a function");
  }
  const callback = useCallback(fn, []);

  useEffect(() => {
    callback();
  }, [callback]);
}

useDebounce真實示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM