iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
自我挑戰組

React自我學習心得30天~系列 第 13

Day13 Composition(組合) vs Inheritance (繼承)

一開始學習React時,常常會使用繼承的方式使用Component,而React官方建議每個Componet之間使用組合的方式複用你寫的程式碼,這可以讓你的程式避免冗長化,也易於管理。

Composition(組合)

Componsitin為多個React Component的組合,如果你在使用某個UI元件B時使用了部分UI元件A的功能時,便是一種組合的概念。用生活中的例子舉例的話,我們吃的火腿蛋三明治由蛋、麵包、火腿三者組合而成,而這三個食材也可以作為其他餐點去使用。

Inheritance (繼承)

Inheritance為React Component之間功能、特性的衍伸,用白話描述的話繼承可以說是指某類事物屬於哪個類別,如手機屬於通訊器材、羽球屬於運動,若UI元件B繼承UI元件A的話,UI元件A為base class(基礎類別),而UI元件B為derived class(衍伸類別)。

Composition和Inheritance的優缺點比較

Inheritance:
優點:可以快速建立專案,繼承後的元件只要針對其需求實作功能即可。
缺點:由於繼承後的元件(derived class)會完全反映出原型元件base class的功能與特色,若後續專案需求有更動的話,由於繼承的特性,修改完原型,繼承的元件也會被改動的關係,造成程式管理不易的情況發生。

RComposition:
優點:相較於繼承,擁有強大的自由度,元件可以只使用你需要用到的功能,避免不必要的功能都繼承下來,讓整個專案更有彈性,而之所以React可以發揮出這麼大的彈性,主要是傳遞外部React元素的Props應用範圍很廣,可以將物件、函式、React元素給下層的component使用。
缺點:剛開始學習時可能不太習慣,需要一點時間來上手。

Composition的使用方式

根據React官網,以下介紹兩種方式:

  1. 包含
  2. 特別化

包含

包含為某一個Component是另一個Component外框的情形,常使用在Sidebar、Dialog這種不知道內容物是什麼的架構上。

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

FancyBorder這個外框提供children這個props,其中children為內容,color為自由帶入的屬性。
利用FacncyBorder這個外框Component,可以讓其他Components將任意的資料作為children帶入。

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

上面的例子為傳入單一內容作為children,Props到component的情形,下面介紹傳入多個component到外框的情形,比如我們想設計一個框架,內容為<header /><menu>組成,可以使用下面的方式組合:

function Header() {
  return <div className="header">Header</div>;
}

function Menu() {
  return <div className="menu"></div>;
}

function Layout(props) {
  return (
    <div className="Layout">
      <div className="layout-header">
        {props.header}
      </div>
      <div className="layout-menu">
        {props.menu}
      </div>
    </div>
  );
}

function App() {
  return (
    <Layout
      header={
        <Header />
      }
      menu={
        <Menu />
      } />
  );
}
ReactDOM.render(<App />,document.getElementById("app"))

特別化

特別化指的是一個Component是另一個Components的特殊情況,比方說將WelcomeDialog當作Dialog的特殊情況,這時只要讓特殊Component渲染通用Component,並用Props去帶入對應的值。

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

上面的案例中便用title和message作為外部傳入的props,去組合成WelcomeDialog這個特別化的Component。

總結

React Components若用Composition方式產出的話,可以避免不必要程式執行,也可以避免後續專案需求調整時整個Component的大幅變動,且React提供了許多好用的Composition功能,如props、HOC、Hooks等,加速專案的開發及後續程式的管理,讓工作變得更輕鬆~


上一篇
Day 12總之待補
下一篇
Day14 用React Component去規劃整個畫面
系列文
React自我學習心得30天~30

尚未有邦友留言

立即登入留言