相关文章推荐
活泼的红烧肉  ·  【Day11】 發生什麼事 - ...·  3 月前    · 
刚失恋的蚂蚁  ·  React ...·  2 月前    · 
爽快的墨镜  ·  能否直接将React ...·  2 月前    · 
很拉风的小狗  ·  React中如何在FileReader的on ...·  2 月前    · 
难过的大熊猫  ·  使用yarn+env-cmd时,如何在cre ...·  4 周前    · 
温文尔雅的绿豆  ·  新华全媒+·图片故事|电力师徒驰援海南抢修-新华网·  9 月前    · 
风流倜傥的热带鱼  ·  全新BMW M5|BMW中国官网·  11 月前    · 
睡不着的毛衣  ·  党委副书记-许佳-云南大学软件学院网站·  1 年前    · 
正直的人字拖  ·  洗脑: ...·  1 年前    · 
曾深爱过的葡萄  ·  悠尼Smart圈粉年轻人洗地机不仅好用价格更 ...·  1 年前    · 
Code  ›  請解釋 useEffect?與 useLayoutEffect 的區別?|ExplainThis
react
https://www.explainthis.io/zh-hant/swe/use-effect-vs-use-layout-effect
聪明伶俐的电影票
1 年前
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
 
推荐文章
活泼的红烧肉  ·  【Day11】 發生什麼事 - Events - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
3 月前
刚失恋的蚂蚁  ·  React Native安卓设备运行报错:包服务器未运行、USB调试未启用及热加载连接失败
2 月前
爽快的墨镜  ·  能否直接将React Native应用运行至iOS设备?类比Android用ADB/SDK直连方式
2 月前
很拉风的小狗  ·  React中如何在FileReader的onload回调中访问局部变量startInt
2 月前
难过的大熊猫  ·  使用yarn+env-cmd时,如何在create-react-app的public目录JS文件注入环境变量?
4 周前
温文尔雅的绿豆  ·  新华全媒+·图片故事|电力师徒驰援海南抢修-新华网
9 月前
风流倜傥的热带鱼  ·  全新BMW M5|BMW中国官网
11 月前
睡不着的毛衣  ·  党委副书记-许佳-云南大学软件学院网站
1 年前
正直的人字拖  ·  洗脑: 毛泽东和后毛时代的中国与世界(Chinese Edition ... - Amazon.com
1 年前
曾深爱过的葡萄  ·  悠尼Smart圈粉年轻人洗地机不仅好用价格更心动- 中国日报网
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号