React Hook使用

要點(diǎn):

  1. 可以在不編寫(xiě)class的情況下使用 state 以及其他react特性。
  2. Hook沒(méi)有破壞性改動(dòng)碱工, 完全是可選的庵寞,且向后兼容茅姜。
  3. 主要是為了解決邏輯復(fù)用的問(wèn)題闪朱。
  4. 鼓勵(lì)開(kāi)發(fā)者將業(yè)務(wù)通用邏輯封裝成React Hook 而不是工具函數(shù)。

動(dòng)機(jī):

  • 在hook出現(xiàn)之前钻洒,React 并沒(méi)有提供一種很好的將可復(fù)用行為‘附加’到組件的途徑(比如連接store),如果想復(fù)用邏輯奋姿,只能通過(guò)render props 或HOC 的形式,但是這樣會(huì)讓組件的結(jié)構(gòu)變得復(fù)雜素标,同時(shí)組件嵌套也太多称诗,造成‘嵌套地獄’(比如很多的Provider 和Consumer)

Hook是什么?

  1. Hook實(shí)際上是一些函數(shù)头遭,這些函數(shù)與React生成的Fiber節(jié)點(diǎn)相關(guān)聯(lián)寓免。
  2. Hook實(shí)際上是利用了閉包,用閉包保存變量计维,并且在合適的時(shí)機(jī)觸發(fā)fiber更新或者執(zhí)行副作用袜香。
  3. Hook依賴(lài)于React特定的上下文,在React之外使用Hook 不會(huì)有任何效果鲫惶。

使用Hooks的好處:

  1. 如果業(yè)務(wù)邏輯變更蜈首,需要在函數(shù)式組件中使用生命周期和狀態(tài), 就不需要再把函數(shù)式組件轉(zhuǎn)化為類(lèi)組件欠母,擴(kuò)大函數(shù)組件的應(yīng)用范圍欢策。
  2. 易于提取可復(fù)用邏輯,是組件更簡(jiǎn)單艺蝴。

Hook使用注意點(diǎn):

  • 不要在條件語(yǔ)句中使用
  • 不要在循環(huán)中使用
  • useEffect 接受的函數(shù)返回值只能是函數(shù)或者undefined.

常用hook

  1. useState()
  • 在組件中保存變量猬腰,在設(shè)置變量時(shí)會(huì)觸發(fā)組件的更新(如果有多個(gè)變量,是否會(huì)觸發(fā)多次更新)猜敢。
  • 接收的參數(shù)可以是值或者函數(shù),如果是函數(shù)盒延,在組件掛載時(shí)執(zhí)行
  • setState會(huì)將這一次的變量和上一次的變量進(jìn)行比較缩擂,如果是同一個(gè),便會(huì)跳過(guò)此次執(zhí)行添寺, 不會(huì)觸發(fā)更新胯盯。
  1. useEffect()
  • 在react的生命周期里執(zhí)行一些副作用(除了狀態(tài)相關(guān)的邏輯,比如網(wǎng)絡(luò)請(qǐng)求计露,監(jiān)聽(tīng)事件博脑,查找 dom)憎乙,接收兩個(gè)參數(shù),第一個(gè)參數(shù)是函數(shù)叉趣,第二個(gè)參數(shù)為依賴(lài)數(shù)組泞边,數(shù)組里的值發(fā)生變化便會(huì)觸發(fā)useEffect,如果數(shù)組為空,默認(rèn)是在組件的掛載和銷(xiāo)毀時(shí)執(zhí)行疗杉。第一個(gè)參數(shù)可返回一個(gè)函數(shù)阵谚,在組件卸載時(shí)執(zhí)行。
  1. useContext()

  2. useMemo()
    const handleClick = useMemo(() => {},[])

  • 同useCallback()用法烟具。
  • useMemo()可返回函數(shù)或者返回值梢什,處理計(jì)算結(jié)果的的緩存或引入組件,防止重復(fù)掛載朝聋。
  • 第二個(gè)參數(shù):不傳數(shù)組嗡午,每次更新都會(huì)重新計(jì)算;傳入空數(shù)組冀痕,只會(huì)計(jì)算一次翼馆;傳入依賴(lài)對(duì)應(yīng)的值,當(dāng)對(duì)應(yīng)的值發(fā)生變化時(shí)金度,才會(huì)重新計(jì)算(可以依賴(lài)另外一個(gè) useMemo 返回的值)
// useMemo示例
function Child({ count }){
  return <p>當(dāng)前傳遞的count為:{count}</p>
}
export default function HookDemo {
  const [count1, setCount1] = useState(0)
  const [count2, setCount2] = useState(10)
  const child = useMemo(() => {
    message.info('重新生成child組件')
    return <Child count={count1} />
  },[count1])
  return <div>{child}</div>
}
  1. useCallback()
    const handleClick = useCallback(() => {callback},[])
  • 存儲(chǔ)參數(shù)中使用的回調(diào)应媚,當(dāng)依賴(lài)數(shù)組發(fā)生變化時(shí),該回調(diào)才會(huì)重新創(chuàng)建猜极。
  • 可以說(shuō)是 useMemo 的語(yǔ)法糖中姜,能用 useCallback 實(shí)現(xiàn)的,都可以使用 useMemo, 在 react 中我們經(jīng)常面臨一個(gè)子組件渲染優(yōu)化的問(wèn)題跟伏,尤其是在向子組件傳遞函數(shù)props時(shí)丢胚,每次 render 都會(huì)創(chuàng)建新函數(shù),導(dǎo)致子組件不必要的渲染受扳,浪費(fèi)性能携龟,這個(gè)時(shí)候,就是 useCallback 的用武之地了勘高,useCallback 可以保證峡蟋,無(wú)論 render 多少次,我們的函數(shù)都是同一個(gè)函數(shù)华望,減小不斷創(chuàng)建的開(kāi)銷(xiāo)
  1. useRef()
  • 一般用取dom引用和組件的值蕊蝗。
  • 在函數(shù)組件中的一個(gè)全局變量,不會(huì)因?yàn)橹貜?fù) render 重復(fù)申明赖舟, 類(lèi)似于類(lèi)組件的 this.xxx
  • 返回一個(gè)可變的ref對(duì)象蓬戚,其.current屬性被初始化為傳入的參數(shù)(initialValue)。返回的ref對(duì)象在組件的整個(gè)生命周期內(nèi)保持不變宾抓。

forwardRef: 應(yīng)用父組件的ref實(shí)例子漩,成為子組件的一個(gè)參數(shù)豫喧,可以引用父組件的ref綁定到子組件自身的節(jié)點(diǎn)上。

  1. useImperativeHandle()
  • 第一個(gè)參數(shù)接收一個(gè)通過(guò) forwardRef 引用父組件的ref實(shí)例幢泼,第二個(gè)參數(shù)為回調(diào)函數(shù)紧显,返回一個(gè)對(duì)象,對(duì)象里面存儲(chǔ)需要(按需)暴露給父組件的屬性或方法旭绒。
    官方建議useImperativeHandle和forwardRef同時(shí)使用鸟妙,減少暴露給父組件的屬性,避免使用ref這樣的命令式代碼挥吵。
    舉例:
function Chindren (props, ref) {
  const childRef = useRef()

  const introduce = useCallback (() => {
    console.log('this is my introduction')
  }, [])
  useImperativeHandle(ref, () => ({
    introduce: () => {
      introduce()
    }
  }));
  return (
    <div ref={childRef }> { props.count }</div>
  )
}

const ChildrenComp= forwardRef(Chindren )

function App () {
  const [ count, setCount ] = useState(0)
  const parentRef = useRef(null)

  const onClick = useCallback (() => {
    setCount(count => count + 1)
    parentRef.current.introduce()
  }, [])
  return (
    <div>
      點(diǎn)擊次數(shù): { count }
      <ChildrenComp ref={parentRef }  count={count}></ChildrenComp>
      <button onClick={onClick}>點(diǎn)我</button>
    </div>
    )
}

8.自定義Hook

  • 基本使用:
// 編寫(xiě)自己的Hook
function useCounter(initialValue){
  const [count, changeCount] = useState(initialValue)
  // 減少
  const decrease = () => { changeCount(count - 1) }
  // 增加
  const increase = () => { changeCount(count + 1) }
  // 重置
  const resetCounter = () => { changeCount(0)}
  return [count, {decrease, increase, resetCounter}]
}
export default function myHookView () {
  const [count, controlCount] = useCounter(10)
  return (
    <div>
       <Button onClick={ controlCount.decrease }>減少</button>
    </div>
  )
}
  • 返回DOM的鉤子
// modal框示例
function useModal(){
  const [visible, setVisible] = useState(false)
  const toggleModalVisible = () => { changeVisible(!visible)}
  return [
    (<Modal visible={visible} onOk={toggleModalVisible(visible)} onCancel={toggleModalVisible}>彈窗內(nèi)容</Modal>), toggleModalVisible]
}

export default function HookDemo () {
  const [modal, toggleModal] = useModal()
  return (
    <div>
      {modal}
      <Button onClick={toggleModal}>打開(kāi)彈窗</button>
    </div>
  )
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末重父,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子忽匈,更是在濱河造成了極大的恐慌房午,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丹允,死亡現(xiàn)場(chǎng)離奇詭異郭厌,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雕蔽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)折柠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人批狐,你說(shuō)我怎么就攤上這事扇售。” “怎么了嚣艇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵承冰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我食零,道長(zhǎng)困乒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任贰谣,我火速辦了婚禮娜搂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冈爹。我一直安慰自己涌攻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布频伤。 她就那樣靜靜地躺著,像睡著了一般芝此。 火紅的嫁衣襯著肌膚如雪憋肖。 梳的紋絲不亂的頭發(fā)上因痛,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音岸更,去河邊找鬼鸵膏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛怎炊,可吹牛的內(nèi)容都是我干的谭企。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼评肆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼债查!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瓜挽,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盹廷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后久橙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體俄占,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年淆衷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缸榄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祝拯,死狀恐怖甚带,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鹿驼,我是刑警寧澤欲低,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站畜晰,受9級(jí)特大地震影響砾莱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凄鼻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一腊瑟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧块蚌,春花似錦闰非、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春辆毡,著一層夾襖步出監(jiān)牢的瞬間菜秦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工舶掖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留球昨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓眨攘,卻偏偏與公主長(zhǎng)得像主慰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鲫售,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 自react16.8發(fā)布了正式版hook用法以來(lái)共螺,我們公司組件的寫(xiě)法逐漸由class向函數(shù)式組件+hook的...
    大春春閱讀 3,970評(píng)論 3 7
  • 在學(xué)會(huì)使用React Hooks之前,可以先看一下相關(guān)原理學(xué)習(xí)React Hooks 前言 在 React 的世界...
    DC_er閱讀 9,095評(píng)論 1 16
  • Hook 是 React 16.8 的新增特性龟虎。它可以讓你在不編寫(xiě) class 的情況下使用 state 以及其他...
    孤獨(dú)的小色狼閱讀 364評(píng)論 0 0
  • 主要介紹 useState useEffect useReducer useContext 用法 你還在為...
    叫我蘇軾好嗎閱讀 27,412評(píng)論 3 41
  • 原教程內(nèi)容詳見(jiàn)精益 React 學(xué)習(xí)指南璃谨,這只是我在學(xué)習(xí)過(guò)程中的一些閱讀筆記,個(gè)人覺(jué)得該教程講解深入淺出鲤妥,比目前大...
    leonaxiong閱讀 2,839評(píng)論 1 18