回顧函數組件
函數組件
沒有組件實例
不能監聽各個生命周期
無法擴展屬性和方法
沒有 state 和 setState
只是輸入 props ,輸出 jsx ,純函數。
?// class 組件class List extends React.Component {constructor(props) {super(props)}render() {const { list } = this.props?return <ul>{list.map((item, index) => {return <li key={item.id}><span>{item.title}</span></li>})}</ul>}}?// 函數組件function List(props) {const { list } = props?return <ul>{list.map((item, index) => {return <li key={item.id}><span>{item.title}</span></li>})}</ul>}
class 組件 vs 函數組件
class 組件有如下問題
大型組件很難拆分和重構,也很難測試。
業務邏輯分散在組件的各個方法之中,導致重復邏輯或關聯邏輯。
組件類引入了 復雜的編程模式,比如 render props 和高階組件。
按照 React 函數式編程的思維來說,一個組件更像一個函數,而不像一個 class ,即 view = fn(props)
所以,函數組件會看起來更簡潔、符合邏輯。
但函數組件沒有 state ,沒有生命周期,還無法取代 class 組件。所以,才有了 React Hooks
。
state hook
函數組件,要求必需是純函數,不能有副作用。因此,要在函數組件使用 state ,不能直接使用,而是要“鉤”進來,這就是 Hooks
那如何把 state “鉤”到函數組件呢?
代碼總結
const [data, setData] = useState(0)
傳入初始值,返回一個數組數組第一個元素,state 值
數組第二個元素,setState 函數
注意命名規范
規定所有 Hook 命名必須是 use 開頭,如 useXxx
自定義的 Hook ,也要 use 開頭
其他地方,不要亂用 useXxx 名字
effect hook
有了 state 之后,還差一個常用的功能 —— 組件生命周期。例如,組件經常會在 didMount 里發請求
模擬聲生命周期
模擬 ComponentDidMount :useEffect
依賴 []
模擬 ComponentDidUpdate :useEffect
無依賴
,或者依賴 [a, b]
模擬 ComponentWillUnMount :useEffect 中
返回一個函數
模擬 ComponentDidMount + ComponentDidUpdate :useEffect
無依賴
effect 實現的是副作用,解釋一下這個詞
純函數,輸入參數,返回結果,不應該有副作用
副作用:對函數之外的干擾,如設置一個定時任務
而組件卻需要副作用,所以用 effect hook 實現
模擬 ComponentWillUnMount 和 class 組件的 WillUnMount 還不一樣。
以一個“監聽好友在線狀態(支持途中好友切換)”的組件為例子說明 —— FriendStatusClass.js
和 FriendStatus.js
,對比著看。
先用 class 組件:演示,光有 WillUnmount 滿足不了需求,需要結合 Update 聲明周期
而用 effect Hook 一步就可以解決問題:
使用 useEffect
無依賴
,實現同時模擬 Update 生命周期所以這里的 “模擬 ComponentWillUnMount” 和 class 組件的 WillUnMount 不一樣
因為模擬 ComponentWillUnMount中 返回的函數 會在
下一次effect
執行之前被執行,無論是更新還是卸載
小結
有了 state ,有了最基本的 3 個生命周期,日常見的功能也就都能做了