iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
Modern Web

重溫 React 官方文件回到最初的起點系列 第 17

Day 17 - State 當作快照(Snapshot)

  • 分享至 

  • xImage
  •  

昨天在介紹 React 如何把畫面呈現在網站上的三個步驟,今天會再針對 state 更新後重新 render 更新畫面再做更多的延伸介紹。
今天的文章參考官方文件的:

Rendering 會即時生成一張快照

當我們更新 state 後,會觸發 render,並且 React 會開始呼叫 component 進行 rendering。而這時候的 component 就會是一個會回傳 JSX 的函式,這個 JSX 就像是螢幕的快照(snapshot),會記錄當下 render 的 state 並計算出的 propevent handler 或區域變數等。React 接著更新畫面,使畫面與你回傳的快照相符。因為在一次 render 只會計算那一次,所以就算在我們的 handler 裡面使用多次 setter 來更新 state,React 都會根據當下 render 所擁有的資料去進行更新。就拿官方文件中的例子:

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 1);
        setNumber(number + 1);
        setNumber(number + 1);
      }}>+3</button>
    </>
  )
}

雖然我們在 onClick 裡面呼叫 setNumber 三次,但最後畫面更新完的數字仍然只有增加 1,這是因為 handler 裡面的 number 在這一次 render 一直都會是 0,所以就算呼叫三次,也只是把 0 變成 1 三次,而不會隨著呼叫次數遞增。它的 event handler 看起來就像是這樣:

<button onClick={() => {
  setNumber(0 + 1);
  setNumber(0 + 1);
  setNumber(0 + 1);
}}>+3</button>

隨著時間改變的 state

接下來再用另一個情境來解釋 state 的快照,那就是在我們的 handler 裡面設定計時器,讓我們點擊按鈕後過一段時間後再執行別的程式碼,藉此來看看畫面有何變化,一樣使用文章中的範例:

import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setTimeout(() => {
          alert(number);
        }, 3000);
      }}>+5</button>
    </>
  )
}

這段程式碼的功能,會是當按下按鈕後,更新 number 這個 state,並且在 3 秒後呼叫 alert 顯示 number 這個 state。大家也可以在按下按鈕前,想想看會產生什麼樣的結果。

答案揭曉,實際操作按下 +5 後,會發現畫面的數字變成 5 了,但經過三秒後,alert 執行的結果跳出提示,會顯示的是一開始的 0。這再次說明了,在同一次 render 裡,state 變數的值永遠不會改變,就算它的 event handler 的程式碼是非同步的。
剛剛 onClick 的執行快照會是:

setNumber(0 + 5);
setTimeout(() => {
  alert(0);
}, 3000);

當 React 透過呼叫 component 來替 UI「拍攝快照」時,state 的值「固定不變」,這是 React 的設定,所以不用擔心 state 在程式碼執行時有所異動。

但有沒有可能在重新 render 前就讀取最新的 state 呢?是可能的,這在明天的文章會進行介紹。

小結

今天把 state 像是快照一樣的概念介紹給大家,希望可以讓大家多了解一點 state 的更新會發生什麼事,幫助以後在開發程式的時候可以更快知道 state 的更新是如何運作的。
今天的文章就介紹到這邊,感謝大家耐心地看完,如果有任何問題與建議歡迎都跟我說,明天見,晚安。


上一篇
Day 16 - Render 和 Commit
下一篇
Day 18 - 將一系列的 State 更新加入隊列
系列文
重溫 React 官方文件回到最初的起點20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言