#### 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 ``` - 時常應用到的範例: - 現在常用的會是在 移除定時器或是監聽器。