相关文章推荐
没有腹肌的自行车  ·  以 React + Express ...·  1 月前    · 
活泼的红烧肉  ·  【Day11】 發生什麼事 - ...·  1 月前    · 
善良的稀饭  ·  合成事件 – React·  1 月前    · 
好帅的饺子  ·  [框架課程] React 19 ...·  1 月前    · 
乐观的西瓜  ·  50天50个小项目 (React19 + ...·  1 月前    · 
安静的熊猫  ·  臺大佛學數位圖書館::: 語言教學.巴利語教學·  9 月前    · 
调皮的小蝌蚪  ·  宁夏大学材料与新能源学院·  1 年前    · 
风流倜傥的熊猫  ·  我校学生斩获“'俄罗斯文艺' ...·  1 年前    · 
仗义的竹笋  ·  【综述】基于弱监督深度学习的图像分割方法综述 ...·  2 年前    · 
愤怒的西瓜  ·  如何有效地打扫家庭卫生? - 知乎·  2 年前    · 
Code  ›  請解釋 useEffect?與 useLayoutEffect 的區別?|ExplainThis
react
https://www.explainthis.io/zh-hant/swe/use-effect-vs-use-layout-effect
聪明伶俐的电影票
9 月前
logo
ExplainThis
  • 軟體前後端
  • 科技業職涯
  • ChatGPT 與 AI
  • 目錄

    • React 面試題詳解 - 導覽
  • React 基礎

    • 什麼是純函式 (pure function)? 為什麼 React 的函式元件需要是純函式?
    • 什麼是 JSX? 為什麼要用 JSX?
    • 請解釋 React 生命週期?
    • 什麼是 Virtual DOM?
  • React Hooks

    • React Hooks 是什麼?
    • 為什麼只能在最頂端層呼叫 Hook?從 useState 實作原理來回答
    • 請解釋 useEffect?與 useLayoutEffect 的區別?
  • React 進階

    • 為什麼 React 渲染列表時需要加上 key?
    • 為什麼更新 React 中的 state 要用 immutable 的寫法? 什麼是 immutable? 該如何寫才會是 immutable?
  1. Home
  2. 軟體前後端
  3. 前後端面試詳解
  4. React

請解釋 useEffect?與 useLayoutEffect 的區別?

2023年2月2日

💎 加入 E+ 成長計畫 如果你喜歡我們的內容,歡迎加入 E+,獲得更多深入的軟體前後端內容

useEffect 是 React 中常用的一個 Hook,也是前端面試中經常被問到的 React 面試題,包括如何使用 useEffect 、useEffect 的執行時機等。另一個與 useEffect 相似的 Hook 是 useLayoutEffect ,這兩者的比較也是 React 面試的高頻題。

useEffect 是什麼?

useEffect 是一個用於連接外部系統的 React Hook。React 的函式元件需要是 純函式 ,但如果我們需要執行具有副作用 (side effect) 的操作,例如:請求 API、使用第三方函式庫,我們就需要將這些程式碼放在 useEffect 中執行。外部系統例如是:伺服器端、瀏覽器提供的 API 或是第三方函式庫。因為這部分不是由 React 本身處理的,所以稱為外部系統。

useEffect 使用方法規則

只能在頂部呼叫

useEffect 也是一種 hook,因此只能在頂層呼叫,不能在迴圈、條件式或者巢狀的 function 中使用,想了解細節的朋友,可以前往這篇文章 《為什麼只能在最頂端層呼叫 Hook?從 useState 實作原理來回答》

useEffect 接受兩個參數:setup function 和 dependencies(可選)

  1. setup function

    setup function:setup function 包含如何連結外部系統的程式碼,如果需要清除邏輯,可以在 setup function 中回傳一個清除 function。

  2. dependencies dependencies 參數是可選的陣列,可以傳入 props、state 或元件中任何使用的變數。React 會使用 Object.is 算法來進行比較, (想了解 Object.is 的細節可以閱讀此篇文章 《在 JavaScript 當中,==、=== 與 Object.is ()的區別》 )。如果 dependencies 中任意一個值與前一次不同,則此 useEffect 會重新執行。。

import { useEffect } from "react";
import { createConnection } from "./blog.js";
function Article(




    
{ articleId }) {
  const [serverUrl, setServerUrl] = useState("https://blog.com/0");
  useEffect(() => {
    const connection = createConnection(serverUrl, articleId);
    connection.connect();
    // 回傳 cleanip function
    return () => {
      connection.disconnect();
  }, [serverUrl, articleId]);
  // ...

useEffect 執行時機

  1. 當元件被加入時 (mount), useEffect 會被第一次執行。
  2. 當每次元件重新渲染時,如果 dependencies 的值有改變,先將舊的 props 和 state 執行 cleanup function,再帶著新的 props 和 state 執行 setup function。
  3. cleanup function 的程式碼,會在元件生命週期結束 (unmount) 時,執行最後一次。

使用 useEffect ,畫面重新渲染時都會閃爍要怎麼解?

解法:嘗試將 useEffect 換成使用 useLayoutEffect 。

以下這一段我們會討論跟 useEffect 很相近的 Hook - useLayoutEffect 。

而標題已經點出來, useLayoutEffect 通常會拿來處理當使用 useEffect 但畫面會出現閃爍的情境,詳細原因下面會提到。

useLayoutEffect 是什麼?

useLayoutEffect 其實是 useEffect 的一種版本,傳入的參數也一樣,只是 執行時機不一樣 ,它會在瀏覽器 重繪 (repaints) 前 執行。

useLayoutEffect 可能會造成性能的問題,因為在 useLayoutEffect 裡的程式碼會阻礙瀏覽器重繪 (repaints) ,太頻繁使用可能會造成整個應用程式緩慢。因此通常會建議先使用 useEffect ,如果不能解決問題,才會選擇使用 useLayoutEffect 。

useEffect 和 useLayoutEffect 比較

以下提供一個程式碼範例,可以明顯感到這兩者差別。 (備註:以下程式碼範例是為了凸顯這兩者差別,實際上開發並不會這樣寫)

程式碼

import { useEffect, useLayoutEffect, useState } from "react";
export default function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    if (count === 0) {
      const randomNum = 1 + Math.random() * 1000;
      setCount(randomNum);
  }, [count]);
  return <div onClick={() => setCount(0)}>{count}</div>;

當我們執行上方程式碼時,連續點擊 div 區塊,會看到畫面產生閃爍。

原因是,當你每次點擊 div,此時 count 會被更新為 0,畫面會重新渲染變為 0,同時,因為 count 被更新,也會觸發 useEffect 執行。所以在重繪完成之後, useEffect 執行並把 count 更新為另一串隨機數字,畫面也會再渲染一次,因為兩次渲染時間很快,所以造成閃爍。

那 useLayoutEffect 的差異是什麼 ?

假設我們把上方程式碼的 useEffect 換成 useLayoutEffect ,當你每次點擊 div,此時 count 會被更新為 0,但這時,畫面不會被重新渲染變為 0,而是先等待 useLayoutEffect 內的程式碼執行完畢之後,state 已經更新為新的隨機數字,這時畫面才進行重繪。

延伸問題

如果不指定 dependencies , useEffect 什麼時候會執行?

此 effect 會是在每次重新渲染元件後重新執行

如果 dependencies 中有 object 會怎麼樣?

下方程式碼的 options 物件會在元件每次重新渲染時,都是不同的物件,所以這個 useEffect 可能會在每次渲染時都重新執行,因為在 dependencies 中的 options 有改變。

function ChatRoom({ articleId }) {
  const [article, setArticle] = useState(null);
	// options 會在每次渲染時重新創建
  const options = {
    serverUrl: 'https://localhost:1234',
    articleId: articleId
  useEffect(() => {
    const data = getArticle(options);
    setArticle(data)
	// options 每次渲染時值都不同,因此觸發 useEffect 執行
  }, [options]);

如果要避免上方程式碼造成不必要觸發 useEffect ,其實可以把動態的物件放在 Effect 中,並把 dependencies 中的物件改為 string 或 number,如下。

function ChatRoom({ articleId }) {
  const [article, setArticle] = useState(null);
  useEffect(() => {
	  const options = {
	    serverUrl: 'https://localhost:1234',
	    articleId: articleId
 
推荐文章
没有腹肌的自行车  ·  以 React + Express 為範例探討 Web 應用中的檔案上傳機制 | Bosh 的技術探索筆記
1 月前
活泼的红烧肉  ·  【Day11】 發生什麼事 - Events - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
1 月前
善良的稀饭  ·  合成事件 – React
1 月前
好帅的饺子  ·  [框架課程] React 19 教學(二)- 基礎語法與核心概念 | 洛奇的邪惡組織手札
1 月前
乐观的西瓜  ·  50天50个小项目 (React19 + Tailwindcss V4) ✨ | DragNDrop(拖拽占用组件)_前端_WOMENshiNIDE-火山引擎 ADG 社区
1 月前
安静的熊猫  ·  臺大佛學數位圖書館::: 語言教學.巴利語教學
9 月前
调皮的小蝌蚪  ·  宁夏大学材料与新能源学院
1 年前
风流倜傥的熊猫  ·  我校学生斩获“&#39;俄罗斯文艺&#39;文学翻译奖·第十三届全球俄汉互译大赛”一 ...
1 年前
仗义的竹笋  ·  【综述】基于弱监督深度学习的图像分割方法综述_51CTO博客_弱 ...
2 年前
愤怒的西瓜  ·  如何有效地打扫家庭卫生? - 知乎
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号