紀錄工作經驗、相關知識,解決技術相關問題。

Javascript, React, 工作雜談, 網站相關

React Console Warning:Support for defaultProps will be removed from function components 原因與解決方法

React Console Warning:Support for defaultProps will be removed from function components 原因與解決方法 特色圖片

在使用 React 開發應用程式時,你可能會在瀏覽器 Console 看到以下警告訊息:

React Console 提示 Support for defaultProps will be removed from function components 警告訊息

這則警告明確指出:Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.

這代表在未來的 React 版本(React 19 及後續版本)中,Function Component(函式元件)將不再支援 defaultProps 語法,開發者應全面改用 JavaScript 原生的「預設參數(Default Parameters)」來處理 Props 預設值。

💡 進階重構與 TypeScript 踩坑導覽:本文專注於 Console 警告觸發原因與 JavaScript 基礎預設參數改法;若你的專案使用 TypeScript,或改寫後遇到 API 傳入 null 導致預設值失效、useEffect 無限重渲染、高階元件(HOC)與 forwardRef 型別問題,請接著閱讀進階篇:解決 React 元件 defaultProps 錯誤:TypeScript Props 預設參數、HOC 與重構踩坑排查。

快速對照:defaultProps vs. JavaScript 預設參數

特性defaultProps (舊式)ES6 預設參數 (新式建議)
定義位置元件函式外部定義函式參數解構時直接定義
TypeScript 相容性型別推導複雜,常需手動處理 Nullable原生支援,型別推導精準且直觀
程式碼簡潔度較冗長,邏輯與定義分離簡潔,邏輯與定義合一
未來相容性React 19+ 預計棄用 (Function Component)符合現代 JavaScript 標準

為什麼 React 官方決定棄用 defaultProps?

React 團隊決定在 Function Component 中移除 defaultProps 主要基於以下工程考量:

  1. TypeScript 型別推導瓶頸:在 TypeScript 中使用 defaultProps 時,編譯器往往難以自動推斷出「雖然外部沒傳入 Props,但內部已有預設值」的邏輯,這常導致開發者必須額外寫 Required<Props> 或手動處理型別斷言。改用 ES6 預設參數後,TypeScript 能直接在參數層級完成精準的型別推導。
  2. 減少執行期開銷:defaultProps 需要 React 在每次渲染時,額外進行一層屬性合併(Shallow Merge)的運算。改用原生語法後,這部分邏輯交由 JavaScript 引擎處理,減少了 React 內部的複雜度。
  3. 語法現代化與一致性:隨著 ES6 解構賦值(Destructuring)與預設參數的普及,defaultProps 這種「掛載在函式物件上的屬性」顯得過時且不直觀。

解決方法:從 defaultProps 遷移至預設參數

1. 觸發警告的舊式寫法 (Problem)

在舊版本中,我們習慣在元件定義完後,額外指定 defaultProps:

const MyComponent = (props) => {
  const { title, description } = props;
  return (
    <div>
      <h1>{title}</h1>
      <p>{description}</p>
    </div>
  );
};

// 這種寫法在未來的 Function Component 中將失效
MyComponent.defaultProps = {
  title: 'Default Title',
  description: 'Default Description',
};

2. 建議的解決思路 (Solution)

直接在參數解構時給予預設值,這是目前 React 官方唯一推薦的處理方式:

// 直接在參數解構處定義預設值
const MyComponent = ({ 
  title = 'Default Title', 
  description = 'Default Description' 
}) => {
  return (
    <div>
      <h1>{title}</h1>
      <p>{description}</p>
    </div>
  );
};

若你的元件不使用解構,也可以這樣寫:

const MyComponent = (props) => {
  const { title = 'Default Title' } = props;
  // ... 略
};

常見問題 (Q&A)

Q1:Class Component 的 defaultProps 也會被移除嗎?

目前 React 官方的計畫主要針對 Function Component。由於 Class Component 的運作機制不同,static defaultProps 在 Class 元件中暫時仍可使用,但建議新專案全面轉向 Function Component。

Q2:如果 Props 是從高階元件 (HOC) 傳進來的怎麼辦?

無論 Props 來源為何,處理邏輯皆一致。在你的目標元件接收 Props 的入口處(即函式參數位元)設定預設值即可。

Q3:使用預設參數會影響效能嗎?

不會。事實上,使用 JavaScript 原生語法減少了 React 框架層級的檢查與合併邏輯,在微觀層面上反而對效能有正面幫助,且大幅提升了程式碼的可讀性與維護性。

Q4:TypeScript 使用者或遇到 null 值時需要注意什麼?

當你改用預設參數時,TypeScript 會自動識別該 Props 為「可選(Optional ?:)」。但要注意:ES6 預設參數只在屬性為 undefined 時生效,若 API 傳入 null 則不會觸發預設值;此外在解構時直接給定 { config = {} } 空物件也容易造成 useEffect 重複執行。關於 TypeScript 完整型別定義、HOC、forwardRef 與這三大重構陷阱的解法,請直接參考專文:解決 React 元件 defaultProps 錯誤:TypeScript Props 預設參數、HOC 與重構踩坑排查。

透過這次變更,React 進一步擁抱了 JavaScript 標準語法,雖然需要調整舊有的撰寫習慣,但長遠來看,這能顯著降低開發者維護元件預設值的複雜度,並確保程式碼在未來版本的相容性。

參考資料與延伸閱讀

發佈留言