React 19.3
概觀
此技能涵蓋 React 19.3 中容易使用錯誤的規則:不應存在的 Effect、依賴陷阱、Actions 及其 Transitions、Server Components 邊界、React Compiler 的採用,以及在 19 版本中移除或棄用的 API。每一個論點都附有其官方文件的頁面連結。
涵蓋的版本
React 19.3,即 react.dev 文件所記錄的版本。先前的主要版本位於 18.react.dev 及更舊的網站上。 https://react.dev/versions
請先閱讀快速入門,然後根據任務開啟對應的參考文件。
快速入門
- 只有在與 React 無法控制的系統進行同步時,才使用 Effect。應在渲染期間推導值,使用
key重置狀態,並在事件處理器中執行由使用者觸發的邏輯。 https://react.dev/learn/you-might-not-need-an-effect - 依賴項應與程式碼保持一致:切勿壓抑
react-hooks/exhaustive-deps。若要移除某個依賴項,請將物件和函數移到 Effect 內部、使用 updater 函數,或從 Effect Event 中讀取值。 https://react.dev/learn/removing-effect-dependencies
const onConnected = useEffectEvent(() => {
showNotification('Connected!', theme);
});
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.on('connected', () => { onConnected(); });
connection.connect();
return () => connection.disconnect();
}, [roomId]);
https://react.dev/learn/separating-events-from-effects
- Effect 必須經歷設定、清理、再設定的過程:Strict Mode 在開發環境下會執行此循環。請修正清理函數,切勿使用 ref 來隱藏第二次的執行。 https://react.dev/learn/synchronizing-with-effects
ref是函數元件的 prop。請使用<Context value={x}>作為 provider。ref 回呼函數可以回傳其清理邏輯。 https://react.dev/reference/react/useRef 及 https://react.dev/reference/react/createContext 及 https://react.dev/reference/react-dom/components/common- 在
startTransition內部的await之後設定的狀態,不屬於 Transition:請將其包在另一個startTransition中。 https://react.dev/reference/react/useTransition - 使用
<form action>時,useActionState的 reducer 會接收(prevState, formData)。請從 Action(例如<form action>或startTransition)中呼叫dispatchAction。 https://react.dev/reference/react/useActionState useFormStatus僅能讀取父層<form>的狀態:請在子元件中呼叫它。 https://react.dev/reference/react-dom/hooks/useFormStatususe(promise)需要一個被快取的 Promise:在渲染期間建立的 Promise 會在每次渲染時重新建立。切勿將use包在try/catch中:請使用 Error Boundary。 https://react.dev/reference/react/use'use server'用於標記 Server Functions,而 Server Components 則沒有 directive。請驗證每一個 Server Function 的引數並檢查授權。 https://react.dev/reference/rsc/server-components 及 https://react.dev/reference/rsc/use-server- 僅限瀏覽器使用的元件:請在
<Suspense>邊界下使用use(browser())(browser來自react-dom),取代typeof window或 mounted 標誌。 https://react.dev/reference/react-dom/browser - 使用 React Compiler 時,請編寫純粹的程式碼,並僅在需要精確控制(例如作為 Effect 的依賴項)時保留
useMemo或useCallback。保留現有的 memoization。 https://react.dev/learn/react-compiler/introduction - 使用
eslint-plugin-react-hooks的recommended配置進行 lint。它包含了 compiler 的規則,因此請移除eslint-plugin-react-compiler。 https://react.dev/blog/2025/10/07/react-compiler-1 - 請在模組層級定義元件,切勿在另一個元件內部定義。 https://react.dev/reference/eslint-plugin-react-hooks/lints/static-components
- 切勿在
&&左側放置數字:count && <p/>會渲染出0。 https://react.dev/learn/conditional-rendering
參考文件
| 文件 | 用於 |
|---|---|
| references/state.md | useState、updater、渲染期間設定、useReducer、不可變更新、狀態結構、key 重置 |
| references/refs-and-context.md | useRef、ref 回呼、ref 作為 prop、useImperativeHandle、context、useId、useSyncExternalStore |
| references/effects.md | 何時不該使用 Effect、useEffect 時機、Strict Mode 清理、資料獲取、useLayoutEffect、useInsertionEffect |
| references/effect-dependencies.md | 移除依賴項、useEffectEvent、自訂 Hook、additionalEffectHooks |
| references/memoization.md | useMemo、useCallback、memo、搭配及不搭配 compiler 的使用 |
| references/react-compiler.md | 安裝、選項、directive、漸進式採用、偵錯 compiler |
| references/rules-and-lints.md | React 規則、Hook 規則、eslint-plugin-react-hooks 規則、Strict Mode |
| references/components-and-tooling.md | Keys、條件式渲染、Fragment refs、Profiler、act、TypeScript、DevTools |
| references/transitions-and-suspense.md | useTransition、startTransition、useDeferredValue、use、lazy、<Suspense> |
| references/view-transitions-and-activity.md | <ViewTransition>、addTransitionType、<Activity> |
| references/actions-and-optimistic.md | useActionState、useOptimistic、useFormStatus、<form action> |
| references/form-elements-and-events.md | 受控輸入、<select>、<textarea>、常見 props、事件、自訂元素 |
| references/server-components.md | Server Components、'use client'、可序列化 props、cache、cacheSignal、taint |
| references/server-functions.md | 'use server'、呼叫 Server Functions、永久連結、安全性 |
| references/client-roots-and-hydration.md | createRoot、hydrateRoot、不匹配、錯誤回報、Error Boundary |
| references/server-rendering.md | renderToPipeableStream、renderToReadableStream、狀態碼、prerender、resume |
| references/dom-apis-and-resources.md | browser、createPortal、flushSync、preload、preinit、<img>、<link>、<script>、<title> |
| references/upgrading-to-19.md | 升級步驟、codemods、移除及棄用的 API、TypeScript 變更、19.2 及 19.3 |
| references/legacy-apis.md | Children、cloneElement、類別元件、forwardRef、PureComponent |
舊有模式
| 舊用法 | 替代方案 | 來源 |
|---|---|---|
forwardRef((props, ref) => ...) | function MyInput({ ref, ...props }) | https://react.dev/reference/react/forwardRef |
<Context.Provider value={x}> | <Context value={x}> | https://react.dev/reference/react/createContext |
<Context.Consumer> render prop | useContext(Context) 或 use(Context) | https://react.dev/reference/react/createContext |
ReactDOM.useFormState | 來自 react 的 useActionState | https://react.dev/blog/2024/12/05/react-19 |
ReactDOM.render、ReactDOM.hydrate | createRoot(el).render()、hydrateRoot | https://react.dev/reference/react-dom |
unmountComponentAtNode | root.unmount() | https://react.dev/reference/react-dom |
findDOMNode | DOM refs | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
字串 ref、this.refs | Ref 回呼或 createRef | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
contextTypes、getChildContext | createContext、static contextType | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
element.ref | element.props.ref | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
react-test-renderer、shallow rendering | Testing Library | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
全域 JSX 命名空間 | declare module "react" { namespace JSX {} } | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
| UMD build script 標籤 | ESM CDN(例如 esm.sh) | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
propTypes | TypeScript | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
函數元件上的 defaultProps | ES 預設參數 | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
import { act } from 'react-dom/test-utils' | import { act } from 'react' | https://react.dev/blog/2024/04/25/react-19-upgrade-guide |
同步 act(() => ...) | await act(async () => ...) | https://react.dev/reference/react/act |
依賴 null 呼叫的 Ref 回呼 | 回傳一個清理函數 | https://react.dev/reference/react-dom/components/common |
使用 renderToString 進行 SSR | renderToPipeableStream 或 renderToReadableStream | https://react.dev/reference/react-dom/server/renderToString |
renderToNodeStream、renderToStaticNodeStream | react-dom/server 串流 API | https://react.dev/reference/react-dom |
| 在伺服器端拋出錯誤以跳過 SSR | use(browser()) | https://react.dev/reference/react/Suspense |
在 Effect 中設定 isClient 狀態、在渲染中使用 typeof window | 在 <Suspense> 下的 use(browser()) | https://react.dev/reference/react-dom/browser |
eslint-plugin-react-compiler | eslint-plugin-react-hooks | https://react.dev/blog/2025/10/07/react-compiler-1 |
"use no forget" | "use no memo" | https://react.dev/reference/react-compiler/directives/use-no-memo |
@vitejs/plugin-react 6 上的 react({ babel: { plugins: [...] } }) | 搭配 @rolldown/plugin-babel 使用 reactCompilerPreset | https://react.dev/learn/react-compiler/installation |
componentWillMount、componentWillReceiveProps、componentWillUpdate | UNSAFE_ 名稱,或該頁面的替代方案 | https://react.dev/reference/react/Component |