# useEffect的作用跟相對應的功能 1. `useEffect` ≒ `componentDidMount`+`componentDidUpdate`+`componentWillUnmount` 2. 對應的功能: `useEffect`接收兩個參數。 - 第一個是一個函式: - 定義 `componentDidMount` 或 `componentDidUpdate` 時要做什麼事 - 此函式的 return 值也要是一個函式,表示 `componentWillUnmount` 時要做什麼事 - 第二個是一個array (dependencies): - 定義當哪些**變數被改變**時,這個 `useEffect` 要重新被觸發。 --- 1. `componentWillUnmount`:如果你的 effect 回傳了一個 function,React 將在需要cleanup時執行它 2. `componentDidMount`:想執行一個 effect 並且僅(在 mount 和 unmount 時)將其執行一次,則可以傳遞一個空 array([])作為第二個參數。這告訴 React 你的 effect 不依賴於任何 props 或 state 的值,因此它不需要重新執行。 3. `componentDidUpdate`:確保 第二個參數的 array 包括了 component 範圍內隨時間變化並被 effect 用到的所有值(例如 props 和 state)。否則,你的程式碼將引用先前 render 中的舊值。 3. 每次 render 後都會執行 useEffect 嗎: >是的!預設情況下,它在第一個 render 和隨後每一個更新之後執行 :::info 把 effect 想成發生在「render 之後」 ::: 4. useEffect 就是在做 side effect 的操作 :::info side effect 1. 資料 fetch 2. 設定 subscription (需要cleanup) 3. 手動改變 React component 中的 DOM ::: 5. cleanup: cleanup在每次**重新render**時都會執行(執行的時間點在執行render前),而不是只在 unmount 組件的時候執行。 :::info 為什麼有些side effect不需要cleanup:因為執行之後就可以被忽略 (幫QQ) ::: - 做了cleanup的例子 (以下使用class component): 這個 component 顯示朋友是否在線上。我們的 class 從 `this.props` 中抓取 `friend.id`,在 component mount 後訂閱好友狀態,並在 unmount 期間取消訂閱: ```jsx= componentDidMount() { ChatAPI.subscribeToFriendStatus( this.props.friend.id, this.handleStatusChange ); } componentWillUnmount() { ChatAPI.unsubscribeFromFriendStatus( this.props.friend.id, this.handleStatusChange ); } ``` **但是如果 component 顯示在螢幕上時,friend prop 發生變化,會發生什麼呢?** :::warning Unmount 時,取消訂閱的呼叫會使用錯誤的朋友 ID (造成 memory leak 或 crash) ::: 6. 對比 useEffect 和生命週期: :::warning 不建議用生命週期的思路去類比思考 useEffect 的執行過程,因爲 useEffect 的執行模式和 componentDidMount 等其他生命週期是不同的 ::: - `useEffect` 可以被看作是每一次渲染之後的一個獨立的函數 ,可以接收 `props` 和 `state` ,並且接收的 `props` 和 `state` 是當次 render 的數據,是獨立的。 - 生命週期 `componentDidMount` 中的 `this.state` 始終指向最新數據 :::info `useEffect` 中不一定是最新的數據,更像是render結果的一部分 (因此才會說 `useEffect` 不會阻止瀏覽器更新螢幕) ::: 7. `useEffect` 和 `useLayoutEffect` 的區別 > `useLayoutEffect` 的使用方法和 `useEffect` 相同,區別是他們的執行時機(以及是否同步執行)。 - `useEffect` 的內容是會在 DOM render 之後執行 (非同步) - `useLayoutEffect` 是在瀏覽器render之前被同步執行 (同步) 例如:在瀏覽器執行下一次render前,需要操作 DOM 改變頁面樣式,如果放在 useEffect 中執行,會出現閃屏問題。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up