在 React 16.8 之前,是用 ES6 Class 來定義 React Component
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
在 React 16.8 之後,可以使用 Function 來定義 React Component
它接受一個「props」(指屬性 properties)物件並回傳描述畫面的 React Element。
我們稱之為 Function Component,因為它本身就是一個 JavaScript Function。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
or
const Welcome = (props) => {
return <h1>Hello, {props.name}</h1>;
}
// const Welcome = props => <h1>Hello, {props.name}</h1>
可以發現 Functional Component 跟 Class Component 經過 Babel 的編譯,轉換成 ES5 程式碼的行數差距,其實滿明顯的。
Class Component 會利用 this.state 去儲存狀態,Function Component 本身不會儲存狀態。
Function Component 沒有內建生命週期程式區塊
如果沒有 State 與 LifeCycle,為什麼要使用 Function Component (簡稱FC)?
React 是使用 Hooks 幫 FC 加上 State 和 LifeCycle
function MyCounter() {
// 使用 useState Hook 加上 State
const [count, setCount] = useState(0);
// 使用 useEffect Hook 加上 LifeCycle (在此是等同於componentDidMount)
useEffect(() => {
document.title = `You clicked ${count} times`;
});
// return 描敘畫面渲染結果的 jsx
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
從程式碼可以觀察到,使用 Hooks 的方式加上 State 和 LifeCycle,
就像是在元件內佈置鈎子,元件本身還是維持它要處理的邏輯,用鈎子掛上希望完成的額外處理。
Function Component 是 Pure Function
FC 程式碼易於閱讀及測試,它就是沒有 State 跟 LifeCycle 的單純 JS Function
Pure Function 的原則是
- 相同輸入永遠是相同輸出
- Function 內只做運算與回傳
- 不對外部世界造成任何改變 (沒有 Side Effect)
- 不會依賴外部變數,只能使用參數傳入
Function Component 的底層執行效率比 Class Componet 好
從前面提到的 Babel 轉譯結果就可以發現,Function Component 轉譯後的程式碼比較少
不會保存內部的私有變數狀態,不會再寫 bind(this) 這種 code
典型的 React Class Component 如下圖
Function Component 不像 Class Component 要使用 this.state 去保存狀態
而是使用 useState (Hook) 的方式,變數不會透過 this 才能去渲染畫面
也表示 FC 相對來說更易於重用及組合,程式碼重構不會被太多相依性綁手綁腳
Class Component 常常會在生命週期中混雜了不同邏輯的方法,無法做整理歸納
透過 FC 搭配 Hooks 可以將相同關聯的邏輯整理在一起,不用被迫根據生命週期將它們拆開來。
觀察下面的邏輯區塊比較
你會發現第二張圖的做法能把有相關的邏輯集中在一塊,寫成客製化的Hooks
FC 直接使用 Hooks 加上所需的功能,不會看到散落在各生命週期的程式碼區塊。
Hook 是一個讓你可以使用 React 各項功能的特殊 Function,
使用 React Hook 之前必須要先知道哪些使用 Hook 的原則,下一篇會詳細說明。
https://zh-hant.reactjs.org/docs/components-and-props.html
https://www.patterns.dev/posts/hooks-pattern/
https://djoech.medium.com/functional-vs-class-components-in-react-231e3fbd7108