Function Component 介紹
在 React 當中,現在有兩種 components。分別是 Class component、Function component(或稱作 Stateless component)。
Function Component 介紹
ES6 語法的 Arrow function 雖然也可以定義 components,但某些情況下它也被看做是 Function component 的一種寫法,因為它的定義方式和 Function component 很像。其中 Function component 和 Arrow function,皆屬於寫 Function component 的方式之一。
class component 是一個復合 React.Component 規格的 Javascript class。class 中必須要有 extend 自 React.Component 的關鍵字。
import React from "react";
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
function component 就是和某些引擎的機制配合下給予 React 更快速運行效能以及更好的 bundle size。另外也可以取用所謂的 hooks 來減少程式碼重複性或是解決各式因為 coomponent 生命周期而產生的問題。
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
arrow component 基本上是 Arrow Function 的特例,透過一個沒有類別內部設定 state 的方式來宣告 Component;基本上語法與 Functional Component 差不多。
一般來說arrow component 也 屬於 Function component
const Greeting = props => {
return <h1>Hello, {props.name}!</h1>;
}
// function component的不同寫法
interface ScrollbarProps {
min: number;
max: number;
step: number;
value: number;
onChange: (value: number) => void;
}
// 第一種
function Scrollbar({ min, max, step, value, onChange }: ScrollbarProps) {
return (
<input type="range" min={min} max={max} step={step} value={value} onChange={(e) => onChange(+e.target.value)} />
);
}
// 第二種
function Scrollbar(props: ScrollbarProps) {
return (
<input type="range" min={props.min} max={props.max} step={props.step} value={props.value} onChange={(e) => props.onChange(+e.target.value)} />
);
}
// 第三種 箭頭function
const Scrollbar: React.FC<ScrollbarProps> = ({ min, max, step, value, onChange }) => {
return (
<input type="range" min={min} max={max} step={step} value={value} onChange={(e) => onChange(+e.target.value)} />
);
};
-
第一種寫法是單純的 JavaScript 函式,接受一個名為
props的物件作為傳入參數,並使用物件解構將需要用到的值取出,最後 return DOM 結構。使用了destructuring assignment,可以直接解構出props中需要的值
function Scrollbar({ min, max, step, value, onChange }) {
return (
<input type="range" min={min} max={max} step={step} value={value} onChange={(e) => onChange(+e.target.value)} />
);
}
-
第二種寫法也是使用函式,但此時使用某個變數(例如
props或someProps)來存放所有屬性和帶入的值,然後回傳 DOM 結構。將整個props傳入,之後再從props中取出需要的值
function Scrollbar(props) {
return (
<input type="range" min={props.min} max={props.max} step={props.step} value={props.value} onChange={(e) => props.onChange(+e.target.value)} />
);
}
- 第三種寫法是使用箭頭函式,代表函式本身就是一個無名函式,其中的命名(例如
Scrollbar)會被當成函式名稱。此外,由於使用箭頭函式,所以部分組件的特殊 property(例如 default values、context、refs)需要額外處理。React 十六版本後預設使用這種寫法。
const Scrollbar = ({ min, max, step, value, onChange }) => {
return (
<input type="range" min={min} max={max} step={step} value={value} onChange={(e) => onChange(+e.target.value)} />
);
};
這三種寫法的 main differance 大多在易讀性和可維護性上,具體的差異在個人口味和開發團隊規範,相對於箭頭函式的寫法,原始函式相對更加明確,可讀性較高。而若使用 TS 再配合 interface 做型別定義,則建議使用第三種寫法可以避免違反程式碼結構盡量平靜的規範。
其他
interface Person {
name: string;
age: number;
}
// 第一種寫法
function ParentComponent() {
const person: Person = { name: 'Tom', age: 20 };
return <ChildComponent person={person} />;
}
function ChildComponent(props: { person: Person }) {
const { name, age } = props.person;
return (
<div>
<p>姓名:{name}</p>
<p>年齡:{age}</p>
</div>
);
}
// 第二種寫法
function ParentComponent() {
const person: Person = { name: 'Tom', age: 20 };
return <ChildComponent {...person} />;
}
function ChildComponent(props: Person) {
const { name, age } = props
return (
<div>
<p>姓名:{name}</p>
<p>年齡:{age}</p>
</div>
);
}
這兩個寫法最主要的差別在 ChildComponent 的 props 定義上。
第一個寫法中,props 定義使用了 inline object,屬性名稱為 person,所以在 ChildComponent 內部需要取得 person 屬性再解構出對應的值。同時,在 ParentComponent 中,定義 person 變數時也聲明了它是一個 Person 型別。
第二個寫法中,props 直接被定義為 Person 型別,屬性名稱即為物件屬性的名稱,因此在 ChildComponent 內部直接就能夠解構出對應的值。同時,在 ParentComponent 中的 ChildComponent 節點處使用了展開運算符(...),把 person 物件中的屬性直接當做 ChildComponent 的 props 值填入。
總體來看,第二個寫法比較簡潔,而且由於不必使用嵌套的 inline object 定義 props,其效能也比第一個寫法更好。不過如果你需要在 ParentComponent 中設定多個按需的 props,那第一種寫法比較方便定義和管理。
Function Component 生命週期
React的Component生命週期分為三個階段: Mounting, Updating 和 Unmounting。
- Mounting:
當 React 將一個 DOM 元素插入到頁面上時,會經歷以下步驟:
- render():返回要渲染的元素列表
- componentDidMount():在組件第一次掛載完成後調用
- Updating:
當 React 檢測到一個組件的 props 或 state 發生改變時,會經歷以下步驟:
- render():返回要渲染的元素列表
- componentDidUpdate(prevProps, prevState, snapshot):在更新後操作 DOM,如添加動畫或發送網路請求
- Unmounting:
當 React 從 DOM 中將一個元素移除時,會調用 componentWillUnmount() 方法。
- componentWillUnmount():組件將被卸載時調用,可以用來取消計時器、清除資源、解除事件綁定等操作。
Component 的生命週期提供了很多方法,開發者可以利用它們在不同的階段做各種操作,例如處理非同步的資料加載、優化 rendering 性能、手動設置 state 等等。