初識React Hooks

最近在新項目中用到了react hooks蛔趴,趁熱乎總結(jié)一下嚣崭。

1. React Hooks是什么&為什么要用React Hooks?

以下引入官方文檔中的簡單介紹:Hook是React16.8的新特性,它可以讓你在不編寫class的情況下使用state以及其他React特性宾尚。

新特定的出現(xiàn)總歸是要解決以往開發(fā)過程中存在的一些問題丙笋,它和之前的版本對比主要有以下優(yōu)勢:
1. 可以再非class的情況下使用更多React特性。(可以不用再使用class來寫react代碼啦)
2. 函數(shù)更加專一化煌贴。(一個函數(shù)只負(fù)責(zé)一塊邏輯的處理御板,而并非將很多不相關(guān)的邏輯都堆在一個函數(shù))
3. 復(fù)用組件的狀態(tài)邏輯。這也是它主要要解決的問題牛郑,但只是狀態(tài)邏輯的復(fù)用怠肋,會共享數(shù)據(jù)的處理邏輯,而非數(shù)據(jù)本身井濒。

2. React Hooks的分類

根據(jù)官方文檔的介紹,React Hooks主要有以下幾種hook:

  • 基礎(chǔ)hook

    • useState:返回一個state和一個更新state的函數(shù)列林,功能類似于class中的state和this.setState瑞你。
    • useEffect: 接收一個包含命令式、且可能有副作用代碼的函數(shù)希痴。它主要可以實現(xiàn)componentDidmount者甲、componentWillUnmount、componentDidUpdate的功能砌创。同時也可以在我們自己封裝的hook中使用useEffect虏缸。
    • useContext: 接收一個context對象,并返回該context的當(dāng)前值嫩实。調(diào)用了 useContext 的組件總會在 context 值變化時重新渲染刽辙。
      useContext(MyContext)只是相當(dāng)于<MyContext.Consumer>,只是能接收到context的值并訂閱其變化甲献。我們?nèi)匀恍枰谏蠈咏M件中用<MyContext.Provider> 來傳遞變化宰缤。
  • 額外的hook

    • useReducer: 它接收一個形如 (state, action) => newState 的 reducer,并返回當(dāng)前的 state 以及與其配套的 dispatch 方法晃洒。可提供類似redux的功能慨灭。
    • useCallback:它接收一個回調(diào)函數(shù)和一個依賴數(shù)組作為參數(shù),返回一個緩存的回調(diào)函數(shù)球及。
    • useMemo:它接收一個回調(diào)函數(shù)和一個依賴數(shù)組作為參數(shù)氧骤,返回一個緩存的值
    • useRef:返回一個可變的 ref 對象吃引,并且在組件的整個生命周期內(nèi)保持不變筹陵,即可跨周期來獲取數(shù)據(jù)刽锤。
    • useImperativeHandle:可以在使用 ref 時自定義暴露給父組件的實例值。
    • useLayoutEffect:如果在useEffect中會操作dom惶翻,那就用useLsyoutEffect來代替姑蓝。它里邊的回調(diào)函數(shù)會在dom更新完成之后執(zhí)行,但在瀏覽器繪制前運行完成吕粗。
    • useDebugValue: 可在React 開發(fā)者工具中顯示自定義 hook 的標(biāo)簽纺荧。

3. 詳解React Hooks

(1) useState

const [count, setCount] = useState(0);其中0作為count的初始值,后續(xù)調(diào)用count來取值颅筋,調(diào)用setCount()來修改值宙暇。

  • 可根據(jù)狀態(tài)之間的關(guān)聯(lián)性來選擇將其設(shè)置為一個狀態(tài)還是多個狀態(tài)。例如
const [name, setName] = useState('susan'); 
const [school, setSchool] = useState('school-one');
//由于name和school都屬于個人信息议泵,所以可以將其放在一個state中占贫。
 const [user_info, setUserInfo] = useState({name: 'susan', school: 'school-one'}); 
  • useState的調(diào)用必須放在頂層調(diào)用,不能在循環(huán)先口、條件語句型奥、嵌套函數(shù)中。
//正確調(diào)用
export const Basic = () => {
    const [count, setCount] = useState(0);
}
//錯誤調(diào)用
export const Basic = () => {
    const flag = 1;
    if(flag){
        const [count, setCount] = useState(0);  
    }
}

必須放在頂層調(diào)用的原因是react對hook的存儲是是按順序的碉京,react會在第一次渲染時將state按useState的順序逐個放到全局的數(shù)組中厢汹,后邊每次更改state都會根據(jù)順序去取state。如果不在非頂層調(diào)用的話谐宙,就會導(dǎo)致根據(jù)初始的序號取不到對應(yīng)的state烫葬。

(2) useEffect:

寫法如下:useEffect(()=>{}, [])

  • 第二個參數(shù)傳與不傳影響很大(第二個參數(shù)為依賴項,可選)
import React, { useState, useEffect } from 'react';
export const BasicInfo = () => {
    const [count, setCount] = useState(0);
    //不寫第二個參數(shù)凡蜻,
    useEffect(()=>{
        document.title = `You clicked ${count} times`;
    })

    //第二個參數(shù)為空
    useEffect(()=>{
        document.title = `You clicked ${count} times`;
    }, [])

    //第二個參數(shù)有值
    useEffect(()=>{
        document.title = `You clicked ${count} times`;
    }, count)
}

以上三種寫法所導(dǎo)致的結(jié)果分別是:

  1. 不寫第二個參數(shù)時:useEffect中第一個函數(shù)參數(shù)在每次渲染后都會執(zhí)行一次搭综。
  2. 第二個參數(shù)為空時:函數(shù)只有在第一次渲染后會執(zhí)行,相當(dāng)于componentDidMount划栓。
  3. 第二個參數(shù)不為空時兑巾,函數(shù)只有在該參數(shù)發(fā)生變化時,才會執(zhí)行忠荞。(可取闪朱,避免了不必要的執(zhí)行)
    注意:useEffect會在每次渲染后都會執(zhí)行,只是第一個回調(diào)函數(shù)會依據(jù)情況來執(zhí)行
  • 依賴項是否發(fā)生了變化钻洒?
import React, { useState, useEffect } from 'react';
export const BasicInfo = () => {
    const [count, setCount] = useState(0);
    const [item_list, setItemList] = useState([]);
    //第二個參數(shù)為基本數(shù)據(jù)類型(趁機回想一下基本數(shù)據(jù)類型都有什么來著奋姿?)
    useEffect(()=>{
        console.log('count...', count);
    }, [count])
    
    //第二個參數(shù)為為引用數(shù)據(jù)類型
    useEffect(()=>{
        console.log('item_liist...', item_list)
    }, [item_list])

    //第二個參數(shù)每次都是一個新的數(shù)組
    useEffect(()=>{
        console.log('item_liist...', item_list)
    }, [...item_list])
}
  1. 當(dāng)?shù)诙€參數(shù)為基本數(shù)據(jù)類型時,那么上述寫法沒有任何問題素标;
  2. 當(dāng)?shù)诙€參數(shù)為引用數(shù)據(jù)類型時称诗,由于react比較依賴是否發(fā)生變化的方法是簡單的比較,所以當(dāng)還是同一個數(shù)組時头遭,它并不會繼續(xù)判斷數(shù)組中的內(nèi)容是否發(fā)生變化寓免,就會直接認(rèn)定該依賴沒有變化癣诱。
    解決辦法就是將依賴項每次都換成一個新的數(shù)組,如第三種寫法袜香。

(3) useContext:

  • 只是替代了consumer撕予,provider該怎么寫還是得怎么寫
// 創(chuàng)建 Context
const Context = React.createContext();//context包含consumer和provider

function Father() {
  return (
  //使用provider給子組件提供數(shù)據(jù)
    <Context.Provider data={'我是父組件的數(shù)據(jù)'}>
      <Son />
    </Context.Provider>
  );
}

// 使用 Consumer 從上下文中獲取數(shù)據(jù)
function Son() {
  return (
    <Context.Consumer>
      {data => <div>{data}</div>}
    </Context.Consumer>
  );
}

//使用useContext從上下文中獲取數(shù)據(jù)
function Son() {
    const data = useContext(Context);
    return <div>{data}</div>;
}

好啦,暫時就以基礎(chǔ)hook作為本次分享的結(jié)尾啦蜈首,因為發(fā)現(xiàn)太長的文章可能看到一半就不太想看了实抡,或者沒有那么長連續(xù)的時間來仔細(xì)看。以上可能在有些地方理解的有出入欢策,歡迎大家來討論哦吆寨。下一篇將繼續(xù)分享額外的hook的一些用法和注意的點。

希望大家能持續(xù)關(guān)注哦踩寇,留一些個人信息方便大家找到我哦啄清。知乎 github
附上個人公眾號哦,希望大家前來騷擾(也會經(jīng)常寫一些隨筆來記錄生活俺孙,畢竟人生漫漫)
[圖片上傳失敗...(image-98a2a6-1585186388805)]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辣卒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子睛榄,更是在濱河造成了極大的恐慌荣茫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懈费,死亡現(xiàn)場離奇詭異计露,居然都是意外死亡博脑,警方通過查閱死者的電腦和手機憎乙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叉趣,“玉大人泞边,你說我怎么就攤上這事×粕迹” “怎么了阵谚?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烟具。 經(jīng)常有香客問我梢什,道長,這世上最難降的妖魔是什么朝聋? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任嗡午,我火速辦了婚禮,結(jié)果婚禮上冀痕,老公的妹妹穿的比我還像新娘荔睹。我一直安慰自己狸演,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布僻他。 她就那樣靜靜地躺著宵距,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吨拗。 梳的紋絲不亂的頭發(fā)上满哪,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音丢胚,去河邊找鬼翩瓜。 笑死,一個胖子當(dāng)著我的面吹牛携龟,可吹牛的內(nèi)容都是我干的兔跌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼峡蟋,長吁一口氣:“原來是場噩夢啊……” “哼坟桅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蕊蝗,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仅乓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蓬戚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夸楣,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年子漩,在試婚紗的時候發(fā)現(xiàn)自己被綠了豫喧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡幢泼,死狀恐怖紧显,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缕棵,我是刑警寧澤孵班,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站招驴,受9級特大地震影響篙程,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜别厘,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一虱饿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦郭厌、人聲如沸袋倔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宾娜。三九已至,卻和暖如春扇售,著一層夾襖步出監(jiān)牢的瞬間前塔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工承冰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留华弓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓困乒,卻偏偏與公主長得像寂屏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子娜搂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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