react hooks 總結(jié)

1.useState

用法:

// initialState也可以接受一個(gè)函數(shù)
const [state, setState] = useState(initialState)

注意事項(xiàng)1: 不可局部更新

  • Q: 如果state是一個(gè)對(duì)象蜜自,能否更新部分state
    A: 不行敬扛,因?yàn)閟etState不會(huì)幫我們合并屬性,解決方法是用擴(kuò)展運(yùn)算符將之前的state對(duì)象擴(kuò)展

注意事項(xiàng)2: 不可局部更新

  • 如果state對(duì)象地址沒有變化蒙畴,那么react就認(rèn)為數(shù)據(jù)沒有變化

注意事項(xiàng)3: setState可以接受函數(shù)為參數(shù)

setState(i => i + 1)

優(yōu)先使用這種方式會(huì)避免一些bug酪耕,比如在一個(gè)函數(shù)點(diǎn)擊中執(zhí)行兩次setState(i + 1),此時(shí)最后的結(jié)果只會(huì)加一次滓彰,但是執(zhí)行兩次setState(i => i + 1)此時(shí)結(jié)果是正常的

2.useReducer

注意事項(xiàng)1: 用來踐行redux思想

  • 分為四部:
  1. 創(chuàng)建初始值initialState
  2. 創(chuàng)建所有操作reducer(state, action)
  3. 傳給reducer控妻,得到讀和寫api
  4. 調(diào)用dispatch寫操作

總的來說useReducer是useState的復(fù)雜版

注意事項(xiàng)2: 如何代替redux

  1. 將數(shù)據(jù)集中在一個(gè)store中
  2. 將所有操作集中在reducer中
  3. 創(chuàng)造一個(gè)Context
  4. 創(chuàng)建對(duì)數(shù)據(jù)讀寫的api
  5. 將第4步的內(nèi)容放到第3部的Context
  6. 用Context.Provider將Context提供給所有組件
  7. 各個(gè)組件用useContext獲取讀寫api

3.useContext

  • 上下文
  1. 全局變量是全局的上下文
  2. 上下文是局部的全局變量
  • 使用方法
  1. 使用C = createContext(initialState)創(chuàng)建上下文
  2. 使用C.Provider圈定作用域
  3. 在作用域內(nèi)使用useContext(C)來使用上下文

4.useEffect

  • 副作用
  1. 對(duì)環(huán)境的改變即是副作用,如修改document.title
  2. 但我們不一定非得把副作用放在useEffect
  3. 實(shí)際上每次都是在render之后執(zhí)行揭绑,可以理解為afterRender
  • 用途
  1. 作為componentDidMount使用弓候,第二個(gè)參數(shù)使用[]
  2. 作為componentDidUpdate使用,可在數(shù)組中指定依賴
  3. 作為componentWillUnMout使用他匪,通過return 函數(shù)使用菇存,組件要卸載的時(shí)候執(zhí)行
  • 如果同時(shí)存在多個(gè)useEffect,會(huì)按照次序執(zhí)行

5.useMemo

  • 理解useMemo
  1. react默認(rèn)會(huì)有多余的render邦蜜,父組件更新撰筷,即使子組件的props沒變,子組件還會(huì)重新渲染畦徘,useMemo的作用是只有props數(shù)據(jù)變了毕籽,子組件才會(huì)重新渲染
  2. 包裹一個(gè)函數(shù)式子組件
  3. 它有一個(gè)bug,即是擁有函數(shù)props的時(shí)候井辆,即使函數(shù)props沒變关筒,它,每次都會(huì)執(zhí)行杯缺,因?yàn)閍pp每次重新渲染都會(huì)重新生成一個(gè)函數(shù)蒸播,兩次函數(shù)不同,所以子組件會(huì)重新渲染。
  4. useMemo還可以接受函數(shù)作為參數(shù)袍榆,這個(gè)方案可以解決上述的bug
useMemo(() => {
  retuen () => {
    //todo
  } //要緩存的函數(shù)
}胀屿,[]) // 需要添加依賴 

useCallback就是為了useMemo方便寫一點(diǎn)創(chuàng)造出來的,二者并沒有太大區(qū)別包雀。如下圖宿崭,此時(shí)不用返回函數(shù),只需要在useCallback寫邏輯即可才写。

useCallback(() => {
  // todo
  console.log(xxx)
}葡兑,[]) // 需要添加依賴 

6.useRef

  • 作用
    在組件render時(shí)不變的值
    用法:ref.current
    至于為什么不能直接使用ref,非得使用ref.current赞草,因?yàn)闉榱吮WC多次useRef是同一個(gè)值讹堤,只有對(duì)象引用才辦得到

在這里可以稍微總結(jié)一下了。

  1. useState/useReducer 每次render的時(shí)候state都會(huì)變
  2. useMemo/useCallback 每次render的時(shí)候厨疙,依賴變了洲守,state就會(huì)變
  3. useRef ,每次render的時(shí)候都不會(huì)變

這里有個(gè)hack操作沾凄,我們可以把ref當(dāng)做state操作

const ref = useRef(0)

const click = () => {
  ref.current += 1
  console.log(ref.current)
}

點(diǎn)擊按鈕的時(shí)候視圖不會(huì)更新梗醇,但是我們打印ref.current會(huì)發(fā)現(xiàn)它變了,我們得想個(gè)辦法讓render執(zhí)行

const ref = useRef(0)
const [m, setM] = useState(0)

const click = () => {
  ref.current += 1
  setM(i => i + 1)
  console.log(ref.current)
}

此時(shí)我們會(huì)發(fā)現(xiàn)視圖也更新了搭独,原因是執(zhí)行setM的時(shí)候會(huì)讓視圖更新婴削,雖然setM這個(gè)函數(shù)跟我們寫的邏輯豪不相關(guān)

7.forwardRef

函數(shù)式組件不能直接使用ref

const ref = useRef(null)
const app = (
  <div>
    <Button ref = {ref}/>
  </div>
)

const Button = (props) => {
  console.log(props)
  return <button></button>
}

此時(shí)會(huì)報(bào)錯(cuò)廊镜,我們看打印信息會(huì)發(fā)現(xiàn)沒有ref屬性牙肝,這是因?yàn)閞eact做攔截了,若想使用ref嗤朴,就得使用了

const ref = useRef(null)
const app = (
  <div>
    <Button2 ref = {ref}/>
  </div>
)

const Button = (props, ref) => {
  console.log(props)
  return <button ref={ref}></button>
}
const Button2 = React.forwardRef(Button)

此時(shí)就能正常使用并且看到ref的打印信息了

那么為什么react要對(duì)props ref作這個(gè)限制呢配椭,可能是大部分時(shí)候不需要用到ref吧

7.useImperativeHandle

這個(gè)名字太難懂了,其實(shí)可以理解成setRef雹姊,也就是最后返回對(duì)ref并且作一些封裝吧股缸,目前沒有用到過

8.自定義hook

封裝hook,一般返回讀接口和寫接口吱雏,但是我們可以自定義返回增刪改查敦姻,這也是hook可以邏輯富用的主要原因

9.Stale Closure

這涉及到hooks心智負(fù)擔(dān)的原理,若想了解可查看我的文章使用react hooks的時(shí)候要注意過時(shí)的閉包

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末歧杏,一起剝皮案震驚了整個(gè)濱河市镰惦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌犬绒,老刑警劉巖旺入,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡茵瘾,警方通過查閱死者的電腦和手機(jī)礼华,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拗秘,“玉大人圣絮,你說我怎么就攤上這事∑钢常” “怎么了晨雳?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奸腺。 經(jīng)常有香客問我餐禁,道長(zhǎng),這世上最難降的妖魔是什么突照? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任帮非,我火速辦了婚禮,結(jié)果婚禮上讹蘑,老公的妹妹穿的比我還像新娘末盔。我一直安慰自己,他們只是感情好座慰,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布陨舱。 她就那樣靜靜地躺著,像睡著了一般版仔。 火紅的嫁衣襯著肌膚如雪游盲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天蛮粮,我揣著相機(jī)與錄音益缎,去河邊找鬼。 笑死然想,一個(gè)胖子當(dāng)著我的面吹牛莺奔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播变泄,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼令哟,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了妨蛹?” 一聲冷哼從身側(cè)響起屏富,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滑燃,沒想到半個(gè)月后役听,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年典予,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甜滨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘤袖,死狀恐怖衣摩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捂敌,我是刑警寧澤艾扮,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站占婉,受9級(jí)特大地震影響泡嘴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逆济,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一酌予、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奖慌,春花似錦抛虫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岛马,卻和暖如春棉姐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛛枚。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工谅海, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脸哀,地道東北人蹦浦。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撞蜂,于是被迫代替她去往敵國(guó)和親盲镶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345