加入互動性
畫面上的某些內容會根據使用者輸入而更新。例如,點擊圖片庫會切換顯示的圖片。在 React 中,隨著時間變化的資料稱為狀態。您可以為任何元件加入狀態,並在需要時更新它。在本章中,您將學習如何編寫能處理互動、更新其狀態,並隨著時間顯示不同輸出的元件。
回應事件
React 允許您在 JSX 中加入事件處理器。事件處理器是您自己的函式,會在回應使用者互動(如點擊、懸停、聚焦於表單輸入等)時觸發。
像<button>這樣的內建元件僅支援瀏覽器的內建事件,例如onClick。然而,您也可以建立自己的元件,並為其事件處理器屬性指定任何您喜歡的應用程式特定名稱。
狀態:元件的記憶
元件經常需要因應互動而改變畫面上顯示的內容。在表單中輸入應更新輸入欄位,點擊圖片輪播的「下一張」應變更顯示的圖片,點擊「購買」會將商品加入購物車。元件需要「記住」一些東西:目前的輸入值、目前的圖片、購物車。在 React 中,這種元件特定的記憶稱為狀態。
您可以使用useStateHook 為元件加入狀態。Hook是一種特殊函式,可讓您的元件使用 React 的功能(狀態是這些功能之一)。useStateHook 讓您宣告一個狀態變數。它接收初始狀態並回傳一對值:目前的狀態,以及一個讓您更新它的狀態設定函式。
以下是一個圖片庫如何使用並在點擊時更新狀態:
渲染與提交
在您的元件顯示於螢幕之前,它們必須由 React 進行渲染。理解此過程中的步驟將有助於您思考程式碼如何執行並解釋其行為。
想像您的元件是廚房裡的廚師,用食材組裝美味的菜餚。在這個情境中,React 是服務生,接收顧客的點單並將訂單送到他們面前。這個請求與提供使用者介面的過程包含三個步驟:
- 觸發一次渲染(將用餐者的訂單送到廚房)
- 渲染元件(在廚房準備訂單)
- 提交到 DOM(將訂單放到桌上)
觸發
渲染
提交
狀態如同快照
與普通的 JavaScript 變數不同,React 狀態的行為更像是一個快照。設定它並不會改變你已有的狀態變數,而是會觸發重新渲染。這起初可能會令人驚訝!
這種行為有助於你避免難以察覺的錯誤。這裡有一個小聊天應用程式。試著猜猜如果你先按下「傳送」,然後將收件人改為 Bob,會發生什麼事。五秒後alert中會出現誰的名字?
排隊進行一系列狀態更新
這個元件有錯誤:點擊「+3」只會將分數增加一次。
狀態如同快照解釋了為什麼會發生這種情況。設定狀態會請求一次新的重新渲染,但不會改變正在執行的程式碼中的狀態。因此,在你呼叫setScore(score + 1) 之後,score 仍然是 0。
你可以透過在設定狀態時傳遞一個更新函數來解決這個問題。請注意,將setScore(score + 1)替換為setScore(s => s + 1)可以修復「+3」按鈕的問題。這讓你可以將多個狀態更新排隊。
更新狀態中的物件
狀態可以保存任何類型的 JavaScript 值,包括物件。但你不應該直接更改儲存在 React 狀態中的物件和陣列。相反地,當你想要更新物件和陣列時,你需要建立一個新的(或複製一個現有的),然後將狀態更新為使用該副本。
通常,你會使用 ...展開語法來複製你想要更改的物件和陣列。例如,更新一個巢狀物件可能看起來像這樣:
如果在程式碼中複製物件變得繁瑣,你可以使用像Immer這樣的函式庫來減少重複的程式碼:
更新狀態中的陣列
陣列是另一種你可以儲存在狀態中的可變 JavaScript 物件,並且應該將其視為唯讀。就像物件一樣,當你想要更新儲存在狀態中的陣列時,你需要建立一個新的陣列(或複製一個現有的陣列),然後將狀態設定為使用新的陣列:
如果在程式碼中複製陣列變得繁瑣,你可以使用像Immer這樣的函式庫來減少重複的程式碼:
接下來呢?
前往 回應事件 開始逐頁閱讀本章!
或者,如果你已經熟悉這些主題,何不閱讀關於管理狀態的內容?
