iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
自我挑戰組

30天CSS、JS、React打造專案零組件系列 第 27

DAY27 - [React] useEffect

今日文章目錄

  • 前言
  • 參考文章

之前提到,useState方法可以讓我在component內部操作資料狀態。
今天來談談另外一個常用到的方法:useEffect

前言

useEffect 使用時機

這裡的Effect指的是「side-effect 副作用」。
也就是說 useEffect是用來處理React component職責以外的額外動作

(舉手提問) React component的職責是什麼?
答:在使用者介面上直接操作資料狀態及回傳節點
就是之前說的:實現 相關UI與邏輯 群組化(component),並回傳React element(JSX)。
(補充後面動作:節點透過ReactDOM.render()放入html檔,瀏覽器解析成 DOM tree,然後渲染成網頁畫面。)

額外動作好比:call api拿資料,直接操作原始DOM(不經過React component),登入 token...等,不是component的主要職責,但需要執行的動作,都可能使用到 useEffect


useEffect syntax

useEffect(function,[state1, props2...])

useEffect()接收兩個參數:

  • function : 執行動作的函式。useEffect()會寫在component裡面,所以函式內也可以操作state
  • [state1, props2...] : 用來比對stateprops狀態,如果狀態有變,執行function,比對項目如果有多組,只要一個有變,function就會執行。

這裡要提到兩個重要概念:React render 順序dependency比對標準: ===

(一) React render 順序

  • 觀察render順序:
    我們利用 console.log() 分別寫在三個位置:一進入 componentuseEffect()內、JSX內。
    console.log() 分別寫在三個位置
    顯示順序:
    顯示順序

可以看到component會先屢行它的主要職責,才進行額外行動:useEffect是在component渲染完後才執行


  • 利用render順序來判斷 : 有無[dependency],程式執行的情況。

React render 順序

------------------------------------- 待確認 -------------------------------------

(二) dependency比對標準: ===

React官網提到dependency比對標準 ===。代表符合改變狀態的標準:
- 同個型別,不同值
- 不同型別,不同值
- 不同型別,同值

OK,那如果dependency要比對物件型別呢?

useEffect(() => console.log("useEffect !"),[{id: 1, name: "Joanna"}])

** 答:compare by Object.is (2021.09.30 update)**。
這會出現一個狀況:如果物件內的屬性改值,但 useEffect()比對物件的位址不變,導致不會執行動作。
如果要解決這樣的問題,有幾個解決方法:

  1. dependency寫到 物件.屬性 (但屬性值要是基礎型別才有效)
const [obj, setObj] = useState({id: 1, name: "Joanna"});
useEffect(() => console.log("useEffect !"),[obj.name])
  1. 既然useEffect()比對物件的位址,那我改位址可以吧!
const [obj, setObj] = useState({id: 1, name: "Joanna"});
useEffect(() => console.log("useEffect !"),[obj])

// 改值:
setObj({...obj, name: "David"})

------------------------------------- 待確認 -------------------------------------


參考文章


上一篇
DAY26 - [React] 登入登出 router
下一篇
DAY28 - [React] useContext 概念篇
系列文
30天CSS、JS、React打造專案零組件30

尚未有邦友留言

立即登入留言