在用Class
制作組件時,經常會用生命周期函數,來處理一些額外的事情(副作用:和函數業務主邏輯關聯不大,特定時間或事件中執行的動作,比如Ajax請求后端數據,添加登錄監聽和取消登錄,手動修改DOM
等等)。在React Hooks
中也需要這樣類似的生命周期函數,比如在每次狀態(State)更新時執行,它為我們准備了useEffect
。從這節課開始來認識一下這個useEffect
函數。它就像一匹野馬,當你沒有馴服它時,感覺它很難相處甚至無法掌握;但你馴服它后,你會發現它溫順可愛,讓你愛不釋手。
用Class
的方式為計數器增加生命周期函數
為了讓你更好的理解useEffect
的使用,先用原始的方式把計數器的Demo增加兩個生命周期函數componentDidMount
和componentDidUpdate
。分別在組件第一次渲染后在瀏覽器控制台打印出計數器結果和在每次計數器狀態發生變化后打印出結果。代碼如下:
import React, { Component } from 'react'; class Example3 extends Component { constructor(props) { super(props); this.state = { count:0 } } componentDidMount(){ console.log(`ComponentDidMount=>You clicked ${this.state.count} times`) } componentDidUpdate(){ console.log(`componentDidUpdate=>You clicked ${this.state.count} times`) } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={this.addCount.bind(this)}>Chlick me</button> </div> ); } addCount(){ this.setState({count:this.state.count+1}) } } export default Example3;
這就是在不使用Hooks情況下的寫法,那如何用Hooks來代替這段代碼,並產生一樣的效果那。
用useEffect
函數來代替生命周期函數
在使用React Hooks
的情況下,我們可以使用下面的代碼來完成上邊代碼的生命周期效果,代碼如下(修改了以前的diamond): 記得要先引入useEffect
后,才可以正常使用。
import React, { useState , useEffect } from 'react'; function Example(){ const [ count , setCount ] = useState(0); //---關鍵代碼---------start------- useEffect(()=>{ console.log(`useEffect=>You clicked ${count} times`) }) //---關鍵代碼---------end------- return ( <div> <p>You clicked {count} times</p> <button onClick={()=>{setCount(count+1)}}>click me</button> </div> ) } export default Example;
寫完后,可以到瀏覽器中進行預覽一下,可以看出跟class
形式的生命周期函數是完全一樣的,這代表第一次組件渲染和每次組件更新都會執行這個函數。 那這段代碼邏輯是什么?我們梳理一下:首先,我們生命了一個狀態變量count
,將它的初始值設為0,然后我們告訴react,我們的這個組件有一個副作用。給useEffecthook
傳了一個匿名函數,這個匿名函數就是我們的副作用。在這里我們打印了一句話,當然你也可以手動的去修改一個DOM
元素。當React要渲染組件時,它會記住用到的副作用,然后執行一次。等Reat更新了State狀態時,它再一詞執行定義的副作用函數。
useEffect兩個注意點
-
React首次渲染和之后的每次渲染都會調用一遍
useEffect
函數,而之前我們要用兩個生命周期函數分別表示首次渲染(componentDidMonut)和更新導致的重新渲染(componentDidUpdate)。 -
useEffect中定義的函數的執行不會阻礙瀏覽器更新視圖,也就是說這些函數時異步執行的,而
componentDidMonut
和componentDidUpdate
中的代碼都是同步執行的。個人認為這個有好處也有壞處吧,比如我們要根據頁面的大小,然后繪制當前彈出窗口的大小,如果時異步的就不好操作了。
轉自:https://jspang.com/posts/2019/08/12/react-hooks.html