搜尋

首頁  >  問答  >  主體

useCallback如何幫助程式碼運行更快?

<p>所以據說,useCallback可以快取一個函數,我認為意圖是為了讓程式碼運作更快。 </p> <p>例如,如果我有:</p> <pre class="brush:js;toolbar:false;"> const handleChange = (ev) => { setMsg(ev.target.value); }; </pre> <p>我也可以改為:</p> <pre class="brush:js;toolbar:false;"> const handleChange = useCallback((ev) => { setMsg(ev.target.value); }, []); </pre> <p>這樣現在函數被緩存了。然而,這個函數不管怎樣都需要在元件重新渲染時建立嗎? </p> <p>為了測試它,我將其改為IIFE,這樣函數就從中輸出出來,它會印出函數正在被輸出。 </p> <p>請參見: https://codesandbox.io/s/jolly-nightingale-zxqp8k</p> <p>所以每當你在輸入框中輸入內容時,都會輸出一個新的函數,如控制台所示。這意味著,IIFE每次都會執行,這也意味著,即使它不是IIFE,函數字面量也會每次都轉換為函數物件。那麼這如何幫助程式碼運行更快呢? </p>
P粉924915787P粉924915787466 天前492

全部回覆(1)我來回復

  • P粉834840856

    P粉8348408562023-08-19 00:29:53

    是的,這是正確的。每次渲染都會建立一個新的函數,然後新的函數會被快取的函數所取代。

    加速並不是因為跳過了創建函數的步驟,而是因為其他程式碼能夠跳過它們自己的工作。這是因為如果它們每次都傳遞相同的函數,它們就知道沒有相關的內容發生了變化。

    例如,如果您需要將handleChange傳遞給useEffect的依賴數組中,每次都傳遞一個穩定的引用非常重要,否則該effect將在每次渲染時重新運行:

    useEffect(() => {
      // ... 使用handleChange做一些事情
    }, [handleChange]);

    或者,如果handleChange作為prop傳遞給一個元件,並且該元件想要使用React.memo跳過渲染。只有在props沒有改變時,才能跳過渲染:

    const Parent = () => {
      const handleChange = useCallback((ev) => {
        setMsg(ev.target.value);
      }, []);
      return <Child handleChange={handleChange}/>
    }
    
    const Child = React.memo(({ handleChange }) => {
      // ... 使用handleChange做一些事情
    })

    回覆
    0
  • 取消回覆