iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
JavaScript

React 觀念架構:從js 基礎到Hook 底層邏輯 系列 第 1

Day1 React 是什麼?從 DOM 痛苦時代到「UI 即函數」的核心心智模型

  • 分享至 

  • xImage
  •  

許多初學者在剛接觸 React 時,常會產生一種錯覺:「React 好難,框架語法好多、邏輯好複雜。」

但如果我們靜下心來將 React 剝開,就會發現:React 本質上只是一個 JavaScript 函式庫 (UI Library)。你在 React 中遇到的大部分瓶頸,其實都不是 React 的問題,而是對 JavaScript 的底層機制理解不夠透徹。

我們先不談複雜的 API 語法,而是先回到最初,聊聊 React 的誕生背景與最關鍵的核心心智模型:UI = f(state)。

一、 噩夢般的 DOM 痛苦時代:命令式編程 (Imperative)

在 React 誕生之前(大約 2010 年前後),前端主流開發方式是使用 原生 JavaScript 或 jQuery。這種開發模式被稱為「命令式編程 (Imperative Programming)」。

所謂的命令式編程,意味著你必須一步步親自告訴瀏覽器該「如何做 (How)」:

  1. 尋找特定的 DOM 節點。
  2. 監聽者的點擊事件觸發。
  3. 手動修改資料變數。
  4. 手動找到對應的 DOM 節點並修改內容。
  5. 手動新增或移除 Class 名稱以改變樣式。

看一個簡單的計數器例子:

    // 傳統 jQuery  寫法
let count = 0;

$('#btn-add').on('click', function() {
  // 1. 修改資料
  count++;
  // 2. 手動更新 DOM 畫面
  $('#count-display').text(count);
  
  // 3. 根據資料手動控制 DOM 狀態與樣式
  if (count > 10) {
    $('#count-display').addClass('warning');
  }
});

傳統寫法帶來的兩大問題:

  • 狀態與 DOM 強烈耦合 (Coupling)
    畫面上的文字、Class 狀態與記憶體中的 count 變數被分散在各個事件監聽器中。當專案規模變大、邏輯變複雜時,你很難知道「目前的 DOM 狀態到底是由哪一段程式碼修改的」。

  • 狀態同步災難 (State Sync Bug)
    一旦忘記手動更新某個 DOM 節點,或是更新順序出錯,就會造成「記憶體裡的資料是 11,但畫面上顯示的卻是 10」的資料不同步問題。

二、 典範轉移:React 與「聲明式編程 (Declarative)」

2013 年,Facebook (Meta) 開源了 React,帶領前端工程界進行了一次偉大的「典範轉移 (Paradigm Shift)」。

React 引入了「聲明式編程 (Declarative Programming)」:你不再需要手動操作 DOM,而是只需要描述「畫面在特定資料狀態下應該長什麼樣子 (What)」,DOM 的實際更新細節則全權交給 React 自動處理。

將剛才的計數器改用 React 來寫:

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <span className={count > 10 ? 'warning' : ''}>
        {count}
      </span>
      <button onClick={() => setCount(count + 1)}>加一</button>
    </div>
  );
}

在 React 中:

完全沒有寫過 document.getElementById 或 innerHTML。

只需要更新 count(State),畫面就會自動同步更新。

三、 React 的核心心智模型:UI = f(state)要學好 React,最重要的一件事就是建立正確的心智模型(Mental Model)。React 最靈魂的核心公式莫過於:UI = f(state)

這個公式說明了一切:

  • state(狀態):應用程式在某個時間點的資料與記憶體狀態。

  • f(組件 / Component):一個純粹的函數。

  • UI(使用者介面):函數接收 state 執行後產生的畫面成果。

    在傳統 DOM 開發中,畫面是持續被增量修改(Mutation)的物件;
    而在 React 裡,畫面是資料在某個特定時間點的「快照 (Snapshot)」。當資料(State)發生改變時,React 會重新執行這個函數 f,傳入新的 State,並算出新的 UI 快照。接著透過 Virtual DOM 與 Diffing 演算法,比對新舊快照之間的差異,最後只精準更新瀏覽器上真正改變的 DOM 節點。

四、 為什麼說「學好 React 的關鍵在於 JavaScript」?

既然 React 的核心是 UI = f(state),這意味著:React 組件本質上就是 JavaScript 函數!許多人在學習 React 時覺得卡關,往往不是因為 React 的 API 太多(常見的 API 其實只有十來個),而是因為對 JavaScript 的語言特性 缺乏深刻的理解。例如:

  • 為什麼 State 不能直接修改? => 牽涉到 JS 的傳值/傳址與記憶體模型 (Memory Model)。
  • 為什麼 useEffect 裡拿到的變數總是舊的? => 牽涉到 JS 的閉包 (Closure) 與作用域鏈。
  • 為什麼 JSX 裡可以寫 map 和 filter? => 牽涉到 JS 的高階函數與運算式求值。
  • 為什麼 Hook 限制不能寫在 if 判斷式內? => 牽涉到 React 底層用 Linked List(鏈表) 儲存狀態的機制。

如果你不了解 JS 的底層機制,寫 React 時就會像在碰運氣,不斷被各種莫名其妙的 Re-render 或無窮迴圈折磨。


下一篇
DAY 2 傳值還是傳址?從記憶體模型看 React 為什麼強調「不可變性 (Immutability)」
系列文
React 觀念架構:從js 基礎到Hook 底層邏輯 7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言