當前大多數網站不再是靜態網站,需要向後端的 Server 請求資料。而且,這些資料的請求通常是非同步進行的。在React中,目前被視為最佳實踐的方式是使用 useEffect。
export default function Component(){
//1.先設置狀態用來儲存從後端獲取的資料
const [data,setData] = useState(null);
useEffect(
() => {
const fetchData = async () => {
const newData = await getDataApi();
setData(newData);
};
fetchData();
},[]);
//2.由於 useEffect 中沒有會觸發的變數,所以 dependency 為 []
return
<>
<p>畫面中其他的東西</p>
{data}
</>
}
在解析上面的程式碼在做什麼之前,我們先來了解甚麼是 useEffect。
useEffect 的參數接收一個function,這個 function 就是副作用,會在每一次 Render 之後執行的。
Render 也就是執行 component 這個 function,useEffect 中的 function (副作用) 會在 function Component 的其他程式碼都執行之後才執行。
接著,我們就來看上面的起手式是如何運作吧。
由此可見,使用 useEffect 來對 API 取得資料會有兩個特點
1.這個元件會執行(Render)兩次
2.在第一次的 data 為預設值(null),在第二次才是從api取得的資料
我一開始使用 useEffect 來取得 API 的資料,感到納悶為甚麼要用這個方式。為甚麼不要一次就把事情做完( Render 一次),要做兩次( Render 兩次)呢?
這樣分兩次做的好處是讓使用者有更好的體驗。在第一次的 render 中,畫面中的其他元素會先被渲染出來,之後在第二次 render 的時候,再把從 api 中取得的資料渲染出來。因為從 API 取得資料需要較長的時間,在第一次 render 時先把主要畫面的元素呈現給使用者看,讓使用者有東西可以先看,使用者比較不會感受到等待取得 API 資料的漫長的時間(如果她的網路很慢的話)。
這就像是我今天跟你借了100萬,我用兩種方式還你錢。
1.我每 3 個月還你 20 萬
2.我一年後一次還你 100 萬
雖然第一種方式我總共用了 15 個月才還完 100 萬,但是你一定覺得第一種方式比第二種方式舒服跟安心多了,你不會在這一年一直擔心我會不會還錢。
在閱讀至此,您可能已經留意到一個重要的問題:
data 只有在 useEffect 中獲取資料後,才會在第二次渲染時擁有實際的數據。
那麼我針對data的處理不就會出錯?
是的,所以在處裡 data 時,要先考慮到 data 沒資料的情況。
解決這個問題的方式有兩種:
// 使用 "data &&" 避免在 data 為 null 或 undefined 時執行相關程式碼或者
if (data) {
data.map(...);
// 或其他處理 data 的程式碼
}
// 使用 "if (data)" 確認 data 不為 null 或 undefined 才執行相關程式碼這樣可以確保相關處理只在 data 有資料時執行,從而避免在第一次渲染時出現錯誤。
if (data) {
data.user...;
// 或其他處理 data 相關的程式碼
}
// 使用 useState 時,將 data 的初始值設為 null
if (data === null) {
return <Loading />;
}
// 此處繼續渲染包含實際資料的 JSX 元素
透過使用 useEffect 來獲取 API 資料,我們可以確保這項相對耗時的非同步操作在第一次渲染後才執行,避免讓使用者在等待 API 資料取得的同時看著空畫面。
同時,我們也必須注意到在第一次渲染時,data 還沒有實際資料,因此在處理資料時需要先考慮這個狀態。