絕對詳細的請看官網:https://react.docschina.org/docs/hooks-intro.html
這里對一些常見的用法和問題進行歸納
為了比較好理解,先說明為什么要弄這個hook
Hook 是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。在未來甚至可以完全覆蓋並替換class的寫法。
使用hook的主要作用是為了讓組件內的邏輯更加清晰,並且可以通過自定義hook來達到復用邏輯。使組件內的邏輯復用性強,且功能清晰明了。
注意:hook只能使用在函數組件中,class組件不支持,所有hook默認約定名稱用use開頭
hook的基本使用
State Hook
用State Hook代替constructor中的this.state
useState hook函數有一個參數,參數可以是任意值,用來進行數據的定義。並且返回一個數組,數組中有兩個對象,第一個是state變量並且把參數值賦予它,第二個是設置這個state變量值的方法,這兩個對象的名稱可自定義
通過useState 函數我們可以定義多個state數據,但我們應該保證每一個state數據都具有意義,同種意義范圍的state數據應該放在同一個state,而不應該拆分成2個state
Effect Hook
用Effect Hook來編寫副作用邏輯代碼,其實就相當於class組件內編寫componentDidMount,componentDidUpdate中的代碼。對應組件生命周期中的Mount階段和Update階段。useEffect同樣可以定義多個
useEffect hook函數每次渲染都會執行,所以不管是掛載還是更新都會觸發它。useEffect是非阻塞的,所以是異步代碼。如果要使用同步的話,請使用useLayoutEffect,這個hook用來進行頁面布局
useEffect有兩個參數。
第一個是副作用函數,用來編寫可能具有副作用的代碼。副作用函數還可以返回一個函數對象,這個函數對象用來清除副作用,不用清除副作用則不用返回。清除階段對應class生命周期中的卸載componentWillUnmount,更新componentWillUpdate
官網的effect運行示意圖,進行下一次更新前總會先清除上一次更新帶來的副作用
第二個參數是數組(可選),里面傳入副作用函數中使用到的數據變量,並且這個變量得具有一定變化的特性,第二個參數主要用於優化,防止進行重復渲染。
eq:這里傳入的數組是[count],count在函數中有使用到,而且count也具有變化性。如果下一次變化后的count與當前的count一樣,則不會執行useState來重新渲染。不同則會渲染更新。
利用這個參數我們也可以實現只在掛載時渲染一次,而后更新時不再渲染。相當於把掛載時只執行一次的代碼寫在componentDidMount
,然后在componentWillUnmount清除代碼副作用。實現這個功能並不需要像class組件必須在不同生命周期函數中編寫代碼,在這里你只需把第二個參數改為一個空數組即可。
useRef Hook
這里獲取了DOM元素p,寫法和API createRef()相似。useRef只能用來保存對象,而沒辦法通過改變useRef.current中的對象來響應式改變頁面
如果父組件想通過ref來控制子組件中的DOM(如何傳遞ref對象),請使用useImperativeHandle Hook,詳情請看https://react.docschina.org/docs/hooks-reference.html#useimperativehandle
使用規則
hook和生命周期函數一樣,必須寫在函數最頂層
而且hook不應該被嵌套進條件或者循環語句中
hook只能在函數組件或者自定義hook中被使用,而不能用於普通函數或者class組件中
自定義Hook
我們可以將一些重復的邏輯代碼,抽離成一個自定義hook,名稱必須以use開頭
補充:hook調用順序
按自身定義的hook順序進行調用
看得出useState只會在初始化時調用一次,而useEffect每次渲染都會調用。每次setState都會觸發更新從而調用useEffect,注意只有setState才會讓數據進行響應式更新,直接設置數據並不會讓頁面進行更新。