一開始學習React時,常常會使用繼承的方式使用Component,而React官方建議每個Componet之間使用組合的方式複用你寫的程式碼,這可以讓你的程式避免冗長化,也易於管理。
Componsitin為多個React Component的組合,如果你在使用某個UI元件B時使用了部分UI元件A的功能時,便是一種組合的概念。用生活中的例子舉例的話,我們吃的火腿蛋三明治由蛋、麵包、火腿三者組合而成,而這三個食材也可以作為其他餐點去使用。
Inheritance為React Component之間功能、特性的衍伸,用白話描述的話繼承可以說是指某類事物屬於哪個類別,如手機屬於通訊器材、羽球屬於運動,若UI元件B繼承UI元件A的話,UI元件A為base class(基礎類別),而UI元件B為derived class(衍伸類別)。
Inheritance:
優點:可以快速建立專案,繼承後的元件只要針對其需求實作功能即可。
缺點:由於繼承後的元件(derived class)會完全反映出原型元件base class的功能與特色,若後續專案需求有更動的話,由於繼承的特性,修改完原型,繼承的元件也會被改動的關係,造成程式管理不易的情況發生。
RComposition:
優點:相較於繼承,擁有強大的自由度,元件可以只使用你需要用到的功能,避免不必要的功能都繼承下來,讓整個專案更有彈性,而之所以React可以發揮出這麼大的彈性,主要是傳遞外部React元素的Props應用範圍很廣,可以將物件、函式、React元素給下層的component使用。
缺點:剛開始學習時可能不太習慣,需要一點時間來上手。
根據React官網,以下介紹兩種方式:
包含為某一個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等,加速專案的開發及後續程式的管理,讓工作變得更輕鬆~