前言
在 React16.8 中,新增hook
功能,能夠在函數組件(Function Component)中使用 state 及其它原本在類組件才能使用的功能。今日我們來試一下怎麼把一個類組件(Class Component)使用新的 Hook 功能改寫成函數組件。
為甚麼要用函數組件
函數組件和類組件最大的區別在於語法
,函數組件就是一個函數接受props
作為參數,返回 React Element。
1 | const Home = props => <div>Welcome, ${props.name}</div>; |
而類組件則需要繼承 React.Component,並實現 render 方法。與函數組件相比,在代碼簡潔程度來說,類組件略遜一籌。
1 | class Home extends React.Component { |
但在 React16.8 之前,函數組件一個致命的弱點,函數組件無法使用 state、refs 和生命週期鈎子,如果要使用這些功能,就必須寫成類組件。
在一些 React 的最佳實踐中推薦能使用函數組件就使用函數組件,當需要用到 state、refs 和生命週期鈎子時才改為類組件。
原因包括:
函數組件代碼更簡潔
因為沒有生命週期和狀態,函數組件更容易測試和閱讀(React16.8前)
更符合最佳實踐中,把組件分為展示組件(Presentation Component)和容器組件(Container Component)的理念
。
要改寫的目標
可以來試試改改傳說 Antd 的組件,挑了一個相對簡單的 BackTop 組件來改。
GitHub: 點我
1 | function getDefaultTarget() { |
先分離一下關注點。這一段的代碼是執行事件的注冊和移除,相應到 Hook 的方法就是useEffect
,useEffect
可以返回函數,該函數將在unmount
時被調用。
1 | componentDidMount() { |
轉換後
1 | useEffect(() => { |
然後是這個很明顯的constructor,是用useState
,useState
返回一個數組,第一個元素就是state,第二個元素就是改變狀態的函數,具體可以在數組解構的時候重新命名,一般的命名習慣是xxx和setXxx,useState
的實踐方法也分為兩種,一種是每一個狀態的調用一次useState
,得到一組的xxx和setXxx,另一種作法是把所有狀態放在一個,只有一個state和setState。
1 | constructor(props: BackTopProps) { |
轉換後
1 | const [visible, setVisible] = useState(false); |
其它的就沒有甚麼特別了,就照抄一遍就行
1 |
|