内容简介:以萬年老梗 counter 來看 State Hook 如何改變 React 寫法,並使用 Custom Hook 加以重構。React 16.8.114 行
以萬年老梗 counter 來看 State Hook 如何改變 React 寫法,並使用 Custom Hook 加以重構。
Version
React 16.8.1
Class Component
App.js
import React, { Component } from 'react';
class App extends Component {
state = {
count: 0,
}
addCount = () => {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<button onClick={ this.addCount }>+</button>
<div>{ this.state.count }</div>
</div>
);
}
}
export default App;
14 行
render() {
return (
<div>
<button onClick={ this.addCount }>+</button>
<div>{ this.state.count }</div>
</div>
);
}
傳統 HTML 的 JSX 要寫在 render()
內,且必須使用 this
才能抓到 state 與 method。
第 4 行
state = {
count: 0,
}
宣告 state
object 儲存 count
state。
第 8 行
addCount = () => {
this.setState({
count: this.state.count + 1
});
}
定義 click
的 event handler: addCount()
,使用 setState()
寫入新的 state。
Class Component 寫法遵循 OOP 風格:使用 side effect 更改 state,且大量使用 this
與 method
Function Component
App.js
import React, { useState } from 'react';
const App = () => {
const [count, setCount] = useState(0);
const addCount = () => setCount(count + 1);
return (
<div>
<button onClick={ addCount }>+</button>
<div>{ count }</div>
</div>
);
};
export default App;
App
由 class 變成 function。
第 7 行
return (
<div>
<button onClick={ addCount }>+</button>
<div>{ count }</div>
</div>
);
不再需要 render()
,只需 return JSX 即可。
也由於 state 與 method 都宣告在 App()
內,連 this
也不需要了。
第 4 行
const [count, setCount] = useState(0);
React 提供了 useState()
hook,傳進 state 的初始值,也就是 0
,回傳兩個值,一個為 state,另外一個為 state 的 setter function,習慣命名為 setXXX()
。
第 5 行
const addCount = () => setCount(count + 1);
定義 click
的 event handler: addCount()
,使用 useState()
hook 提供的 setCount()
寫入新的 state。
Function Component 寫法遵循 FP 風格:不使用 side effect 更改 state,也沒有使用 this
與 method
,全都是一進一出的 Pure Function,且行數從 24 行精簡到 15 行
Custom Hook
Q:若將來 App()
太大要重構,或其他 component 要重複使用這段邏輯該怎麼辦 ?
counter.js
import { useState } from 'react';
export const useCount = () => {
const [count, setCount] = useState(0);
const addCount = () => setCount(count + 1);
return [
count,
addCount,
];
}
我們將 count
state 與 addCount()
抽成 useCount()
hook,單獨放在 counter
module 中。
由於 JSX 需要的只有 count
state 最後結果與 addCount()
,最後再將這兩個以 array 方式傳回。
React 官方建議 custom hook 都以 use
開頭。
App.js
import React from 'react';
import { useCount } from './counter';
const App = () => {
const [count, addCount] = useCount();
return (
<div>
<button onClick={ addCount }>+</button>
<div>{ count }</div>
</div>
);
};
export default App;
App()
只要接收 useCount()
hook 所傳回的值即可。
我們可以發現由於 Function Component 的 Hook 寫法,因為沒有 side effect,都是 Pure Function,所以特別容易重構,只要簡單的 Extract Function,然後搬到其他 module 即可
Conclusion
- 有了 State Hook,使得原本必須在 Class Component 才能有的 state,目前在 Function Component 也能達成
- 由於 Function Component 都是 Pure Function,因此特別容易重構成 Custom Hook
-
Component 間牽涉 state 的邏輯若有重複,只要簡單抽成 Custom Hook 再 import 進來即可,不必再使用
render props或higher-order component
Sample Code
完整範例可以在我的 GitHub 上找到
Reference
Reed Barger, React Hooks
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。