iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
Modern Web

30 days of React 系列 第 14

Day 14 - React 的渲染機制以及 state 的過程

  • 分享至 

  • xImage
  •  

先前我們在補充中有稍微提到 Reac 的渲染機制,今天將更深入地學習 React 的渲染是怎麼一回事。

渲染的三階段

當我們在 React 當中組織了元件,並將元件渲染,這樣會經過三個過程「觸發(triggering)」→「渲染(rendering」→「提交(commiting)」。

第一步:觸發渲染(triggering)

觸發的情況又可以分為二種情況,初始渲染(initial render) 再渲染(re-render)。

初始渲染也就是元件的第一次渲染,而當元件的 state 被更新則會處發 re-render。如同我們昨天學到的,可以透過 set function 操作。

第二步:渲染元件(rendering)

當完成觸發後,React 會渲染元件,若是初始渲染的話,React 會調用根元件(root component),也就創造 DOM nodes 。而在後續的渲染中,React 則會調用觸發渲染的狀態並更新元件。

第三步:提交更動(committing changes)至 DOM

初始渲染的情況,React 會使用 appendChild()DOM API,將所有的 DOM nodes 創造出來。而再次渲染的情況,React 僅會處理在第二步所計算(calculate)的更動來做改有必要的最小幅改動。

re-rendering

流程

我們再細看一點第二部渲染元件時,當是 re-render 的情況時,也就是使用了 set function 像是 useState,這時 React 則會再次呼叫 function,function 會回傳一個新的 JSX。可以想像這樣子回傳 JSX 時,我們拍了一張快照,記錄了當下渲染的資料。

要留意,因為是「快照」,所以每次渲染紀錄的是該次渲染的資料。

在這樣的快照記錄下,React 也能掌握什麼東西應該要更新,這個過程也可以稱為「協調(reconciliation)」

state

剛剛的過程中,經歷了 state 的運用,當 React 使用了 state 時,我們又可以怎麼去理解呢?昨天談到了 state 就如同「狀態」儲存了該狀態的資料,當 function return 結束時,state 並不會消失,state 會像是擺在架上的工具一樣,當我們所需的時候,(也就是 React 調用元件的時候),再把它從書架上拿下來紀錄該次的快照。

一個例子

學習完剛剛的知識,若是下方的例子裡:alert 的值會因為設定了 setTimeout 而改變嗎?

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>
    </>
  );
}

由於狀態變數不會在一個渲染中改變值,而渲染的機制如同快照一般紀錄了當下的資料。所以 alert number 的值依然會是 0。

那 React 渲染結束後呢?

當 React 的渲染完成,也提交更動後,這時瀏覽器會進入渲染畫面(browser rendering),而使用者就能在頁面上看到渲染的結果。

以上是今天的學習,這個篇章 React 文件裡有相當多淺而易懂的插圖,可以參考看看。

參考資料

  • React 官方文件 - Render and Commit, State as a Snapshot
  • The Joy of React by Josh W Comeau - The useState Hook, Core React Loop

上一篇
Day 13 - 在React中使用state
下一篇
Day 15 - React 渲染:排隊任務
系列文
30 days of React 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言