首頁 >web前端 >js教程 >函數組件等於函數式程式設計嗎?

函數組件等於函數式程式設計嗎?

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-22 02:32:13182瀏覽

Do Function Components Equal Functional Programming?

React開發者對React有兩種元件類型早已熟悉:

  • 類別組件
  • 函數組件

考慮到「類別」和「函數」的提及,自然會產生疑問:

  • 類別元件與物件導向程式設計(OOP)有關嗎?
  • 函數元件與函數式程式設計(FP)有關嗎?

畢竟,如果類別元件與OOP相關,那麼OOP原則(繼承、封裝、多態等)可以指導基於類別的元件的開發。類似地,FP原理可以影響函數組件。換句話說,我們可以直接將這些程式設計範式的最佳實踐應用到React專案中。

那麼,函數元件和函數式程式設計之間是什麼關係呢?本文將深入探討此主題。

程式設計範式與DSL

首先,我們應該明確,框架語法本質上是一種DSL(領域特定語言),專為特定領域的開發而定制。

例如,React是用於建立視圖的DSL。雖然不同的平台使用不同的框架來建立視圖,例如:

  • Web端:ReactDOM
  • 小程式:Taro
  • 原生開發:位元組跳動的內部框架React Lynx

這些框架通常遵循相同的DSL(React語法)。此DSL不與任何特定的程式設計範式綁定,而應被視為一套非常適合視圖開發的語言特性集合。

因此,作為React DSL的一部分:

  • 函數元件可以體現OOP原則。
  • 類別組件可以反映FP原則。

只要這些原則有利於視圖開發,就可以將它們整合到DSL中。

例如,考慮以下由WelcomeMessage和LogoutButton組成的函數元件Header,這示範了OOP中組合優於繼承的原則:

<code class="language-javascript">function Header(props) {
  return (
    <div>
      <WelcomeMessage name={props.name} />
      <LogoutButton onClick={props.onLogout} />
    </div>
  );
}</code>

同樣,考慮類別元件Cpn,其中狀態count的更新不是透過變異(this.state.count ),而是透過使用不可變資料呼叫this.setState:

<code class="language-javascript">class Cpn extends React.Component {
  // ...
  onClick() {
    const count = this.state.count;
    this.setState({ count: count + 1 });
  }
  render() {
    // ...
  }
}</code>

使用不可變資料反映了FP的原則。

因此,在探索任何React特性時,我們應該考慮以下三個步驟:

  1. React的核心開發理念是什麼?
  2. 哪些來自各種程式設計範式的想法被用來實現這種理念?
  3. 這些思想如何在React應用?

透過將此思考過程應用於函數組件和函數式程式設計之間的關係,我們發現:

  • 函數元件是實現的結果(步驟3)。
  • 函數式程式設計是一種程式設計範式(步驟2)。

這定義了它們之間的關係:函數元件是在React中實現多種程式設計範式(主要是OOP和FP)的產物,在此過程中藉鑒了FP的一些想法。

函數元件不應僅被視為React中函數式程式設計的體現。

函數組件的演變

讓我們使用前面提到的三步驟思維過程來探討函數組件的演變。 React的開發理念最好用以下公式表達:

<code class="language-javascript">function Header(props) {
  return (
    <div>
      <WelcomeMessage name={props.name} />
      <LogoutButton onClick={props.onLogout} />
    </div>
  );
}</code>

為了實現這個理念,需要兩個關鍵要素:

  • 資料快照
  • 函數映射

在這裡,來自FP的不可變資料更適合作為資料快照的載體。這就是為什麼React中的狀態是不可變的——狀態的本質就是一個快照。

函數映射的載體沒有特定的要求。在React中,每次更新都會觸發重新渲染,而渲染過程本身就是函數映射過程。輸入是props和state,輸出是JSX。

相較之下,Vue組件較符合OOP原則。考慮這個Vue App元件:

<code class="language-javascript">class Cpn extends React.Component {
  // ...
  onClick() {
    const count = this.state.count;
    this.setState({ count: count + 1 });
  }
  render() {
    // ...
  }
}</code>

元件的setup方法只在初始化期間執行一次。後續更新操作在閉包內操作相同的數據,這對應於OOP中實例的概念。

由於React不會對函數映射的載體施加特殊要求,因此類別組件和函數組件都是可行的選擇。

為什麼函數元件取代了類別元件?

許多人認為,透過hook改進邏輯的可重複使用性是函數元件優於類別元件的主要原因。然而,基於裝飾器的類別開發模型,尤其是在與TypeScript結合使用時,已被證明是一種有效的邏輯重用方法。

真正的原因在於函數元件能夠更好地實現UI = fn(snapshot)的理念。

如前所述,公式中的快照代表狀態的快照,在React中包含:

  • state
  • props
  • context

對於給定的元件,公式UI = fn(snapshot)確保相同的快照產生相同的輸出(JSX)。但是,狀態更新也可能觸發副作用,例如資料擷取或DOM操作。

在類別元件中,這些副作用邏輯分散在各種生命週期方法中,使得React難以控制。但在函數元件中:

  • 副作用被限制在useEffect。 React確保在應用新的副作用之前清理來自先前渲染的副作用(透過useEffect的回傳值)。
  • ref的傳播透過forwardRef等機制受到限制,限制了其潛在的影響。
  • 資料取得副作用由Suspense管理,如下所示:
<code>UI = fn(snapshot);</code>

用法:

<code class="language-javascript">const App = {
  setup(initialProps) {
    const count = reactive({ count: 0 });
    const add = () => { count.value++; };
    return { count, add };
  },
  template: "...omitted"
};</code>

簡而言之,函數元件確保副作用保持可控,從而為相同的快照輸入提供一致的輸出。這與FP中純函數的概念相符,這就是為什麼函數元件已成為React中的主流選擇。

結論

函數元件不是React中函數式程式設計的直接實現,而是實現React核心理念UI = fn(snapshot)的最合適的載體。 React整合了來自各種程式設計範式的優秀思想,其中FP的影響最大。最終,每個設計選擇都服務於整體理念。


我們 Leapcell,是您託管 Node.js 專案的首選。

Do Function Components Equal Functional Programming?

Leapcell 是新一代無伺服器平台,用於 Web 託管、非同步任務和 Redis:

多語言支援

  • 使用 Node.js、Python、Go 或 Rust 進行開發。

免費部署無限項目

  • 僅按使用付費-無請求,無收費。

無與倫比的成本效益

  • 隨選付費,無空閒費用。
  • 範例:25 美元支援 694 萬次要求,平均回應時間為 60 毫秒。

簡化的開發者體驗

  • 直覺的 UI,輕鬆設定。
  • 完全自動化的 CI/CD 管道和 GitOps 整合。
  • 即時指標和日誌記錄,提供可操作的見解。

輕鬆擴充與高效能

  • 自動擴充以輕鬆處理高並發。
  • 零營運開銷-只需專注於建置。

在文件中了解更多!

Do Function Components Equal Functional Programming?

追蹤我們的 X:@LeapcellHQ


閱讀我們的部落格

以上是函數組件等於函數式程式設計嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn