昨天認識了第一個Hook-useState
,今天要繼續認識useEffect
這個語法。有時候,在開發React程式時會希望在網頁render後能夠更新一些值,或是取得API的資料,這時候就是useEffect
派上用場的地方了。
useEffect
是一個用來執行side effect的語法,會在component渲染後執行。常用的side effect有像是AJAX、手動改變component的DOM等等。useEffect
需要放入一個function,供其執行。
useEffect(()=>{
// something
})
舉個例子,假設今天我們要在使用者按按鈕後,document的標籤顯示點擊次數,可以這樣做:
const {useState, useEffect} = React;
const App = () => {
const [count, setCount] = useState(0);
useEffect(()=>{
document.title = `您按了${ count }次 `
})
const handleClick = ()=>{
let newCount = count + 1;
setCount(newCount);
}
return (
<div>
<button onClick={handleClick}>加一</button>
</div>
)
}
執行這段程式碼的話可以看到,每按一次,document的title就會更改,顯示出按了幾次。
每當state更新、頁面re-render後,useEffect
便會重新執行一次,無論有沒有state在function裡面。
從下圖可以見得,只要count
更新,console.log(“Hello”)
就會被執行。
如果不希望每次re-render都執行useEffect
,只要在需要的時候執行的話,可以在第二個參數位置放入含特定state的Array:
// 只需要在count 更新時執行
useEffect(()=>{
document.title = `您按了${ count }次 `
}, [count])
這樣就會只在第一次render以及指定的state更新時執行useEffect
了。
如果希望useEffect
只在第一次render執行,可以在第二個參數位置放入一個空Array,代表沒有可偵測到的條件,這樣就會只在第一次時執行。
useEffect(()=>{
console.log(“Hello”)
}, [])
這樣的做法很適合使用在串接API上,若網頁只需要取得一次資料,就可以用這個方法在第一次render後取得API的資料。
不過如果要異步處理串接資料的話,要注意不要直接加async
在useEffect的callback function上面,原因在於useEffect
的第一個參數必須回傳undefined或是一個function,但是asynchronous function回傳的是Promise,與useEffect
期望的回傳值不同,會出現錯誤。
若要用asynchronous function取資料(如fetch),可以參考下面作法:
useEffect(() => {
const fetchData = asnyc () => {
const data = await fetch(“url”);
}
fetchData()
.then((data) => {
console.log(data)
})
.catch(err=>{
console.log(err)
})
}, [])
或者用IIFE(立即執行函式):
useEffect(() => {
(asnyc () => {
const data = await fetch(“url”);
console.log(data)
})()
}, [])
useEffect
不只可以放一個,因此可以在fetch資料後再寫一個useEffect
執行其他功能,相當的方便,如果熟悉並活用useEffect的話,對React程式開發上有很大的幫助!