BridgeCraft logobridgecraft
週報顧問服務作品集關於聯絡登入
聯絡

bridgecraft

從資料視覺化到 AI Agent,一直在找下一個 meta

文章主題指南週報顧問服務Labs作品集系統架構關於聯絡RSS

© 2026 BridgeCraft — Waiting7777. All rights reserved.

← 所有文章

React 18 新功能研讀

2021年7月15日 · Waiting7777 · 3 分鐘閱讀

What’s coming in React 18

在計畫中有提到了三個主要新功能

  • automatic batching
  • startTransition
  • new streaming ssr with React.lazy

並且計劃在讓舊版本在最小的改動之下,就能使用這些提升而不用重寫整個專案。

Automatic Batching

what is batching?

React 18 會在核心中新增這項改進,一般用戶甚至不會意識到有這變化,不過還是來看看什麼是 batching 。

batching 是 React 把多個狀態更新濃縮成單個,來達到更好的效能,以底下這段 code 來說,每次點擊會觸發兩次 setState,然後 react 會把這兩次濃縮成一次更新,只會觸發一次 re-render。

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); // Does not re-render yet
    setFlag(f => !f); // Does not re-render yet
    // React will only re-render once at the end (that's batching!)
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

這是個很棒的功能,可以減少很多不必要的 re-render ,也不會再出現那種狀態更新到一半的情況。但是,現階段的 React 並沒有辦法處理全部的更新,目前的 React 只能將事件裏的更新 batch 起來,像是底下這種在 fetch 之後的 setState ,就無法處理了。

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 17 and earlier does NOT batch these because
      // they run *after* the event in a callback, not *during* it
      setCount(c => c + 1); // Causes a re-render
      setFlag(f => !f); // Causes a re-render
    });
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
} 

在 React 18 前,只有 event handler 裡面的更新會被 batch, promise 、 setTimeout 、 native event 等等都是不會被 batch 的。

What is automatic batching

在 React 18 中使用 createRoot ,所有的更新就都會 batch 了。

import * as ReactDOM from 'react-dom';
import App from 'App';

const container = document.getElementById('app');

// Create a root.
const root = ReactDOM.createRoot(container);

// Initial render: Render an element to the root.
root.render(<App tab="home" />);

// During an update, there's no need to pass the container again.
root.render(<App tab="profile" />);

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 18 and later DOES batch these:
      setCount(c => c + 1);
      setFlag(f => !f);
      // React will only re-render once at the end (that's batching!)
    });
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

在 React 18 中 fetch 、 promise 、 setTimeout 等等的 setState 行為就一樣了。

startTransition

在大型專案裡,如果做個 filter 來 filter 一個很大的 table ,有時候會導致畫面的卡頓,舉例來說你可能會寫成這樣:

// Urgent: Show what was typed
setInputValue(input); // light

// Not urgent: Show the results
setSearchQuery(input);  // heavy

其實使用者比較希望馬上看到 inputValue 的變化,這樣的互動感覺是好的,而 table 的變化可以稍微的慢一點沒關係,但原本的寫法還是得等到整個結果完成才 render。

現在有新的 api startTransition 可以使用

import { startTransition } from 'react';

// Urgent: Show what was typed
setInputValue(input);

// Mark any state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});

在 React 中更新有兩種策略

  • Urgent updates: reflect direct interaction, like typing, clicking, pressing, and so on.
  • Transition updates: transition the UI from one view to another.

在更新時只要告訴 React 那些更新是可以設定為 Transition updates 那麼這些更新就會是可以被 interrupt 的。

Suspens SSR Architecture

在 React 中 SSR 通常有以下幾個步驟:

  • Server 端,fetch 整個 app 的 data
  • 接著 server render 出整個 app 要用的 HTML 並且回傳
  • 接著 client 接收整包的 javascript code
  • 接著 client 將 javascript 與 server-generated HTML 連結 (hydration)

關鍵的是每個步驟都是要處理整個 app 的 fetch 與 render,導致當app太大時反而很慢。

在 React 18 中可以用 <Suspense> 來將整個 app break down 成較小的獨立單位,來讓 SSR可以分開進行。

Streaming HTML and Selective Hydration

原本的 SSR

<main>
  <nav>
    <!--NavBar -->
    <a href="/">Home</a>
   </nav>
  <aside>
    <!-- Sidebar -->
    <a href="/profile">Profile</a>
  </aside>
  <article>
    <!-- Post -->
    <p>Hello world</p>
  </article>
  <section>
    <!-- Comments -->
    <p>First comment</p>
    <p>Second comment</p>
  </section>
</main> 

client 端會先收到

https://camo.githubusercontent.com/e44ee4be56e56e74da3b9f7f5519ca6197b24e9c34488df933140950f1b31c38/68747470733a2f2f717569702e636f6d2f626c6f622f5963474141416b314234322f534f76496e4f2d73625973566d5166334159372d52413f613d675a6461346957316f5061434668644e36414f48695a396255644e78715373547a7a42326c32686b744a3061

接著 load javascript 並且 hydrate

React 18 中的 SSR

<Layout>
  <NavBar />
  <Sidebar />
  <RightPane>
    <Post />
    <Suspense fallback={<Spinner />}>
      <Comments />
    </Suspense>
  </RightPane>
</Layout>

將 <Comments /> 放到 <Suspense/> 中, 就是告訴 React,不用等 <Comments /> 裡的東西。

https://camo.githubusercontent.com/484be91b06f3f998b3bda9ba3efbdb514394ab70484a8db2cf5774e32f85a2b8/68747470733a2f2f717569702e636f6d2f626c6f622f5963474141416b314234322f704e6550316c4253546261616162726c4c71707178413f613d716d636f563745617955486e6e69433643586771456961564a52637145416f56726b39666e4e564646766361

另外在 client 端也可以加入 lazy 來讓前端的 code 是分段載入的,而不是一大包。

import { lazy } from 'react';

const Comments = lazy(() => import('./Comments.js'));

// ...

<Suspense fallback={<Spinner />}>
  <Comments />
</Suspense>

心得

以上就是 React 18 計畫裡提到的三個新功能,看起來都是加入了 fiber 以後,讓 react render 變得更有彈性,所以在做功能時可能要想到耦合度不要太高,能夠功能區塊切割完整的話,未來才能享用這些新功能。

每週一篇 — 技術趨勢背後的商業邏輯

分享:

Waiting7777

WoW Arena 冠軍轉前端,用電競 meta 思維拆解技術趨勢。

關於作者

相關文章

YC 裡越來越多二次創業者 — AI 時代為什麼老手反而更吃香創業創投+4

YC 裡越來越多二次創業者 — AI 時代為什麼老手反而更吃香

為什麼 AI 時代反而讓「老手」更吃香?從 YC 的數據看 repeat founder 的優勢在哪,以及這對第一次創業的人有什麼啟示。

2026年8月12日 · Waiting7777 · 7 分鐘閱讀

繼續閱讀 →
OpenChamber:專為 AI Agent 設計的開發環境,跟 IDE 的差別在哪?AI Agents開發工具+5

OpenChamber:專為 AI Agent 設計的開發環境,跟 IDE 的差別在哪?

拆解 OpenChamber 的設計邏輯:為什麼 agent 需要專屬的開發環境、跟直接在 terminal 跑 Claude Code 有什麼本質差異,以及這個方向的商業潛力在哪。

2026年8月11日 · Waiting7777 · 8 分鐘閱讀

繼續閱讀 →
AI coding 工具燒錢有多快?Databricks 告訴你怎麼控成本AI開發工具+4

AI coding 工具燒錢有多快?Databricks 告訴你怎麼控成本

從「Databricks 燒完錢才搞出控制工具」這個角度切入,拆解 AI coding 工具的真實成本結構,以及企業在 scale up 後才發現的坑。對比 Rippling 同樣在燒錢後才蓋 ROI 工具,這是一個系統性問題。

2026年8月8日 · Waiting7777 · 7 分鐘閱讀

繼續閱讀 →

這篇文章對你有幫助嗎?

每週一篇 — 技術趨勢背後的商業邏輯

AI 產業在變什麼、工程師該注意什麼——拆清楚寄到你的信箱。