---
# System prepended metadata

title: 01. useEffect 面試考題&概念紀錄 - 逐日更新
tags: [Hooks, useEffect]

---

#### 01.

- 講解一下 useEffect：
  - useEffect , 是 React 其中一個 Hooks
    主要的作用是用於瀏覽器渲染完以後，去執行副作用操作
    應用的場景：
    - 需要在**組件加載後獲取數據或訂閱某些事件時**

```jsx
// 基本操作：

function MyComponent() {
  useEffect(() => {
    // 在這裡執行副作用操作

    return () => {
      // 在組件卸載或依賴變更時執行清理操作
    };
  }, [/* 依賴項 */]); -> 這邊通常會是一個 [] , 也可以丟變數在裡面
}
```

#### 02.

1. 寫依賴項：
   假設我們不在代碼填入依賴項 `[]`
   **當 useEffect 裡的 setCount 觸發執行 re-render時 
   就會再一次執行 useEffect ()**，促使無限迴圈的發生
   不填寫依賴項目並非導致無限迴圈的原因。
```jsx
// 以下為參考：

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount((prevCount) => prevCount + 1);
    console.log("count 無限迴圈 ~~~", count);
  }); -> }) 之間沒有寫入空[]依賴

  return (
    <>
      <span>{count}</span>
    </>
  );
}
// 沒錯，就是給你無限 loop 
```

2. 填入依賴項 `[]`，沒有綁定特定變量在裡頭，`useEffect`段代碼只會在組件渲染完畢以後，加載一次：

```jsx
function App() {
  useEffect(() => {
    console.log("這是一則載入訊息~");
  }, []); // 載入依賴項[]
}

- console 訊息
// 這是一則載入訊息~
// 這是一則載入訊息~
```

3. 有實際的依賴變量情況範例：
   - 參考下列的步驟順序：

```jsx
function App() {
  const [num, setNum] = useState(0);

    // 02. click 以後，觸發了函數，重新渲染，使數值+1
  const handleIncrement = () => {
    setNum((prev) => prev + 1);
  };

  useEffect(() => {
      // 03-1. useEffect , 這邊會判斷，依賴變數[num]  是否有變化
      // 03-2. 有的話，才會去執行下列 console.log message
    console.log("useEffect 觸發後：", num);
  }, [num]);

  return (
    <div>
      <span>{num}</span>
             // 01. user 透過點擊按鈕來觸發事件
      <button onClick={handleIncrement}>增量</button>
    </div>
  );
}
```








#### 03. 關於 useEffect 裡頭的 return「return function cleanup」：

- 這邊我們可以去觀察一下這個 Example:



```jsx
import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
  const [num, setNum] = useState(0);
  console.log("start:", num);
  useEffect(() => {
    console.log("Effect", num);

    // 返回清理函數
    return () => {
      console.log("clean", num);
      // 這裡用來卸載 render 之前的 state
    };
  }, [num]);

  const handleIncrement = () => {
    setNum((prev) => prev + 1);
  };

  return (
    <div>
      <span>{num}</span>
      <button onClick={handleIncrement}>增量</button>
    </div>
  );
}

export default App;

```

#### 04. return function cleanup 是卸載 re-render 前 / 後?

```jsx
// 初次載入時：
start: 0
installHook.js:1 start: 0
Effect 0
clean 0
Effect 0
// 輸入行為以後
start: 1
start: 1
clean 0 // -> 由此可以看出， clean up 是先清除 re-render 前的 state
Effect 1 // -> 卸載以後，才觸發 re-render
```
#### 05. useEffect 裡的 return , clean up 是清理什麼？為什麼需要清理?


```jsx
// Clean up 是清除 , useEffect 的函式內容
Ex , 假設設定了一個非同步 setTimeout 動作 , 預期兩秒後才會執行此行為
假設這時候使用者快速跳轉 other pages(切換頁面) , 這時候會產生 memory leak  

假設有執行 clean up (), 在執行跳轉 pages 時可以避免這個問題發生


不過針對  memory leak 這問題 
據說這是 v17 才會有的問題 , 在 v18 假設不撰寫 return clean up ()
React 也會幫你做一次清除的動作 , 避免發生  memory leak
```

- 時常應用到的範例：

  - 現在常用的會是在 移除定時器或是監聽器。




