React如何處理非同步的資料-useEffect的使用方法與設計影響

閱讀時間約 5 分鐘



當前大多數網站不再是靜態網站,需要向後端的 Server 請求資料。而且,這些資料的請求通常是非同步進行的。在React中,目前被視為最佳實踐的方式是使用 useEffect。

用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。

useEffect 的參數接收一個function,這個 function 就是副作用,會在每一次 Render 之後執行的。

Render 也就是執行 component 這個 function,useEffect 中的 function (副作用) 會在 function Component 的其他程式碼都執行之後才執行。

運作的方式與順序

接著,我們就來看上面的起手式是如何運作吧。

  1. 第一次執行 App 的 function(第一次 Render)
    1. 用useState設置 state 變數- data (目前是 null)
    2. return 包含 data 的 HTML (其實是 React Element)
    3. 最後執行 useEffect中的 function ,發送 API 取得 newData ,並用以更新 data (變成newData)
    4. 因為 執行了 setData,且 data 的值有改變,所以觸發第二次 Render
  2. 第二次執行App 的 function (第二次 Render)
    1. App 函數再次被呼叫,但此時 data 的值已經是由 API 取得的新數據 newData
    2. 返回的 JSX 元素中的 data 將呈現最新的資料
    3. 沒有 state 變化會在觸發 render與 useEffect ,所以程式中止

由此可見,使用 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 萬,但是你一定覺得第一種方式比第二種方式舒服跟安心多了,你不會在這一年一直擔心我會不會還錢。

因應第一次 Render 沒資料的設計

在閱讀至此,您可能已經留意到一個重要的問題:

data 只有在 useEffect 中獲取資料後,才會在第二次渲染時擁有實際的數據。

那麼我針對data的處理不就會出錯?

是的,所以在處裡 data 時,要先考慮到 data 沒資料的情況。

解決這個問題的方式有兩種:

  1. 使用條件判斷避免錯誤: 在處理 data 的程式碼之前,可以加上以下其中之一的條件判斷:
    // 使用 "data &&" 避免在 data 為 null 或 undefined 時執行相關程式碼
    if (data) {
    data.map(...);
    // 或其他處理 data 的程式碼
    }
    或者
    // 使用 "if (data)" 確認 data 不為 null 或 undefined 才執行相關程式碼
    if (data) {
    data.user...;
    // 或其他處理 data 相關的程式碼
    }
    這樣可以確保相關處理只在 data 有資料時執行,從而避免在第一次渲染時出現錯誤。
  2. 搭配 loading 元件: 另一種方法是搭配 loading 元件,在第一次渲染時返回這個 loading 元件:
    // 使用 useState 時,將 data 的初始值設為 null
    if (data === null) {
    return <Loading />;
    }
    // 此處繼續渲染包含實際資料的 JSX 元素


總結

透過使用 useEffect 來獲取 API 資料,我們可以確保這項相對耗時的非同步操作在第一次渲染後才執行,避免讓使用者在等待 API 資料取得的同時看著空畫面。

同時,我們也必須注意到在第一次渲染時,data 還沒有實際資料,因此在處理資料時需要先考慮這個狀態。

    歡迎來到我的部落格!這裡是一個分享前端開發、貓咪寫真以及與菲律賓女友生活的文化衝擊與英文學習的個人空間。我熱愛前端技術,喜歡追求最新的網頁開發趨勢,並將這些知識分享給大家。
    留言0
    查看全部
    avatar-img
    發表第一個留言支持創作者!
    我在學習vue的過程中,一開始是先從輕前端(用CDN引入)開始學。這時候看Vue的官方文件會有些困惑,原因是有沒有用vite建構,在元件寫法上會有些差異。所以我寫下這篇筆記來整理這兩者寫法上的差異。 起手式 1.非建構:使用cdn 在html的header中插入以下script標籤 <s
    我相信大家應該都有在表單上看過開關元件,那麼我們會拿它來做甚麼?要怎麼把它做出來?
    Media query可以很複雜,但是這裡KP只談最簡單、最實用的基礎。
    對於前端工程師而言,如何處理圖片是一個看是基本但是又重要的技能。就像是日本料理的師傅要懂得處理生魚片一樣。 因為flexbox的flex-item有自動伸縮的功能,所以要注意裡面的圖片如何被伸縮。
    在上一篇文章-跟著KP用21天征服Responsive Layout-W2-Flexbox基礎-flex-item的伸縮 。我們提到了flex-item的width會由自身的內容長度決定。這其實是件很不可控的事情,所以我們在開發上會傾向於對flex-item設置width。 flex-item
    在學習了flexbox的起手式之後,讓我們來檢視與優化html結構吧。 <section class="three-col"> <div class="container"> <!--用來設置layout--> <div class="row"> <!-
    我在學習vue的過程中,一開始是先從輕前端(用CDN引入)開始學。這時候看Vue的官方文件會有些困惑,原因是有沒有用vite建構,在元件寫法上會有些差異。所以我寫下這篇筆記來整理這兩者寫法上的差異。 起手式 1.非建構:使用cdn 在html的header中插入以下script標籤 <s
    我相信大家應該都有在表單上看過開關元件,那麼我們會拿它來做甚麼?要怎麼把它做出來?
    Media query可以很複雜,但是這裡KP只談最簡單、最實用的基礎。
    對於前端工程師而言,如何處理圖片是一個看是基本但是又重要的技能。就像是日本料理的師傅要懂得處理生魚片一樣。 因為flexbox的flex-item有自動伸縮的功能,所以要注意裡面的圖片如何被伸縮。
    在上一篇文章-跟著KP用21天征服Responsive Layout-W2-Flexbox基礎-flex-item的伸縮 。我們提到了flex-item的width會由自身的內容長度決定。這其實是件很不可控的事情,所以我們在開發上會傾向於對flex-item設置width。 flex-item
    在學習了flexbox的起手式之後,讓我們來檢視與優化html結構吧。 <section class="three-col"> <div class="container"> <!--用來設置layout--> <div class="row"> <!-
    你可能也想看
    Google News 追蹤
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    前言 create react app 是一個可以快速設定 react 專案的一個工具,在建立專案時已經把 babel,webpack 都已經預先封裝設置好,如果我們要修改 webpack alias 設定該如何設定呢 什麼是 alias alias 在 webpack 設定意義叫做,檔案路徑
    Thumbnail
    在現代的前端開發中,有許多優秀的框架可供選擇,其中包括Angular、React和Vue.js。這些前端框架都擁有自己獨特的特點和優勢,但在選擇合適的框架時可能會感到困惑。本文將介紹Angular、React和Vue.js這三個常見的前端框架的特點和優勢,並分析各個框架的使用情境和適用範圍。
    Thumbnail
    動態導覽列為增加使用者經驗UX,要如何在Tailwind CSS上實現呢?這次JayLin來帶大家做一個動態導覽列(Animation Navigation)
    Thumbnail
    想要知道如何用最新技術來製作一個App嗎? 跟著JayLin用React | Redux Tool Kit | TypeScript | TailwildCSS 來製作一個Drawing App
    Thumbnail
    相信最近有不少輸歐企業接到進口商有關Y-code的詢問,自己的輸歐產品在清關時被海關要求提供最新的Y-code及相關檔。 Y-code,是歐盟地區海關系統中證件編碼(Document coding)中的一種,它是商品進出口報關時所要求提供的代碼資訊,以反映申報商品的屬性和合規資訊。
    Thumbnail
    接續上一篇,這邊要來寫一個React hello world app,最後安裝webpack-dev-server來提升開發效率。 使用npm安裝react, react-dom: $ npm install react react-dom --save dependencies下紀錄的是生產環境會
    Thumbnail
    React開發有兩種方式,一種是使用CDN方式include react的官方lib,然後使用babel來將JSX編譯成瀏覽器看得懂的javascript。 但是在react中還會使用到sass, scss等等,還需要額外編譯成css瀏覽器才看得懂。 而webpack的誕生,就是為了解決上述的問題,
    Thumbnail
    在各種「高仿」球鞋猖獗的現在,應該多少令喜歡 Hype 球鞋的你感到困擾吧?越是熱門的鞋款出現仿製品的機會也就越高。今回,MIXFIT 便要扮演著糾察隊的角色,帶各位了解 2018 鞋王之一的 UNDERCOVER x Nike React Element 87 真假分別之處!
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    前言 create react app 是一個可以快速設定 react 專案的一個工具,在建立專案時已經把 babel,webpack 都已經預先封裝設置好,如果我們要修改 webpack alias 設定該如何設定呢 什麼是 alias alias 在 webpack 設定意義叫做,檔案路徑
    Thumbnail
    在現代的前端開發中,有許多優秀的框架可供選擇,其中包括Angular、React和Vue.js。這些前端框架都擁有自己獨特的特點和優勢,但在選擇合適的框架時可能會感到困惑。本文將介紹Angular、React和Vue.js這三個常見的前端框架的特點和優勢,並分析各個框架的使用情境和適用範圍。
    Thumbnail
    動態導覽列為增加使用者經驗UX,要如何在Tailwind CSS上實現呢?這次JayLin來帶大家做一個動態導覽列(Animation Navigation)
    Thumbnail
    想要知道如何用最新技術來製作一個App嗎? 跟著JayLin用React | Redux Tool Kit | TypeScript | TailwildCSS 來製作一個Drawing App
    Thumbnail
    相信最近有不少輸歐企業接到進口商有關Y-code的詢問,自己的輸歐產品在清關時被海關要求提供最新的Y-code及相關檔。 Y-code,是歐盟地區海關系統中證件編碼(Document coding)中的一種,它是商品進出口報關時所要求提供的代碼資訊,以反映申報商品的屬性和合規資訊。
    Thumbnail
    接續上一篇,這邊要來寫一個React hello world app,最後安裝webpack-dev-server來提升開發效率。 使用npm安裝react, react-dom: $ npm install react react-dom --save dependencies下紀錄的是生產環境會
    Thumbnail
    React開發有兩種方式,一種是使用CDN方式include react的官方lib,然後使用babel來將JSX編譯成瀏覽器看得懂的javascript。 但是在react中還會使用到sass, scss等等,還需要額外編譯成css瀏覽器才看得懂。 而webpack的誕生,就是為了解決上述的問題,
    Thumbnail
    在各種「高仿」球鞋猖獗的現在,應該多少令喜歡 Hype 球鞋的你感到困擾吧?越是熱門的鞋款出現仿製品的機會也就越高。今回,MIXFIT 便要扮演著糾察隊的角色,帶各位了解 2018 鞋王之一的 UNDERCOVER x Nike React Element 87 真假分別之處!