React Hook簡介

本文引自

https://zh-hans.reactjs.org/docs/hooks-intro.html

HookReact 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性连躏。

注意
React 16.8.0 是第一個支持 Hook 的版本剩岳。升級時,請注意更新所有的 package入热,包括 React DOM拍棕。 React Native 從 0.59 版本開始支持 Hook晓铆。

一、Hook沒有破壞性改動

在我們繼續(xù)之前绰播,請記住 Hook 是:

  • 完全可選的骄噪。 你無需重寫任何已有代碼就可以在一些組件中嘗試 Hook。但是如果你不想蠢箩,你不必現(xiàn)在就去學(xué)習(xí)或使用 Hook链蕊。
  • 100% 向后兼容的。 Hook 不包含任何破壞性改動滔韵。
  • 現(xiàn)在可用掌实。 Hook 已發(fā)布于 v16.8.0。

沒有計劃從 React 中移除 class宴卖。 你可以在本頁底部的章節(jié)讀到更多關(guān)于 Hook 的漸進策略症昏。

Hook 不會影響你對 React 概念的理解拘悦。 恰恰相反,Hook 為已知的 React 概念提供了更直接的 API:props分苇, state医寿,context蘑斧,refs 以及生命周期。稍后我們將看到沟突,Hook 還提供了一種更強大的方式來組合他們惠拭。

如果不想了解添加 Hook 的具體原因,可以直接跳到下一章節(jié)開始學(xué)習(xí) Hook棒呛! 當(dāng)然你也可以繼續(xù)閱讀這一章節(jié)來了解原因域携,并且可以學(xué)習(xí)到如何在不重寫應(yīng)用的情況下使用 Hook。

二趋观、使用Hook的動機

Hook 解決了我們五年來編寫和維護成千上萬的組件時遇到的各種各樣看起來不相關(guān)的問題拆内。無論你正在學(xué)習(xí) React宠默,或每天使用搀矫,或者更愿嘗試另一個和 React 有相似組件模型的框架瓤球,你都可能對這些問題似曾相識敏弃。

問題1:在組件之間復(fù)用狀態(tài)邏輯很難

React 沒有提供將可復(fù)用性行為“附加”到組件的途徑(例如,把組件連接到 store)绿饵。如果你使用過 React 一段時間拟赊,你也許會熟悉一些解決此類問題的方案粹淋,比如 render props高階組件桃移。但是這類方案需要重新組織你的組件結(jié)構(gòu),這可能會很麻煩过吻,使你的代碼難以理解第步。如果你在 React DevTools 中觀察過 React 應(yīng)用缘琅,你會發(fā)現(xiàn)由 providers廓推,consumers,高階組件呻纹,render props 等其他抽象層組成的組件會形成“嵌套地獄”雷酪。盡管我們可以在 DevTools 過濾掉它們涝婉,但這說明了一個更深層次的問題:React 需要為共享狀態(tài)邏輯提供更好的原生途徑。

你可以使用 Hook 從組件中提取狀態(tài)邏輯吩跋,使得這些邏輯可以單獨測試并復(fù)用锌钮。Hook 使你在無需修改組件結(jié)構(gòu)的情況下復(fù)用狀態(tài)邏輯引矩。 這使得在組件間或社區(qū)內(nèi)共享 Hook 變得更便捷旺韭。

具體將在自定義 Hook 中對此展開更多討論。

問題2:復(fù)雜組件變得難以理解

我們經(jīng)常維護一些組件混蔼,組件起初很簡單珊燎,但是逐漸會被狀態(tài)邏輯和副作用充斥悔政。每個生命周期常常包含一些不相關(guān)的邏輯。例如槽地,組件常常在 componentDidMountcomponentDidUpdate 中獲取數(shù)據(jù)捌蚊。但是,同一個 componentDidMount 中可能也包含很多其它的邏輯挺智,如設(shè)置事件監(jiān)聽窗宦,而之后需在 componentWillUnmount 中清除。相互關(guān)聯(lián)且需要對照修改的代碼被進行了拆分媒怯,而完全不相關(guān)的代碼卻在同一個方法中組合在一起髓窜。如此很容易產(chǎn)生 bug,并且導(dǎo)致邏輯不一致杨拐。

在多數(shù)情況下,不可能將組件拆分為更小的粒度帆阳,因為狀態(tài)邏輯無處不在。這也給測試帶來了一定挑戰(zhàn)山宾。同時资锰,這也是很多人將 React 與狀態(tài)管理庫結(jié)合使用的原因之一阶祭。但是,這往往會引入了很多抽象概念鞭盟,需要你在不同的文件之間來回切換齿诉,使得復(fù)用變得更加困難。

為了解決這個問題歇竟,Hook 將組件中相互關(guān)聯(lián)的部分拆分成更小的函數(shù)(比如設(shè)置訂閱或請求數(shù)據(jù))焕议,而并非強制按照生命周期劃分馋记。你還可以使用 reducer 來管理組件的內(nèi)部狀態(tài),使其更加可預(yù)測宽堆。

我們將在使用 Effect Hook 中對此展開更多討論畜隶。

問題3:難以理解的 class

除了代碼復(fù)用和代碼管理會遇到困難外号胚,我們還發(fā)現(xiàn) class 是學(xué)習(xí) React 的一大屏障猫胁。你必須去理解 JavaScript 中 this 的工作方式,這與其他語言存在巨大差異届惋。還不能忘記綁定事件處理器菠赚。沒有穩(wěn)定的語法提案衡查,這些代碼非常冗余。大家可以很好地理解 props俱饿,state 和自頂向下的數(shù)據(jù)流塌忽,但對 class 卻一籌莫展砚婆。即便在有經(jīng)驗的 React 開發(fā)者之間突勇,對于函數(shù)組件與 class 組件的差異也存在分歧甲馋,甚至還要區(qū)分兩種組件的使用場景迄损。

另外芹敌,React 已經(jīng)發(fā)布五年了,我們希望它能在下一個五年也與時俱進碧聪。就像 Svelte液茎,Angular捆等,Glimmer等其它的庫展示的那樣,組件預(yù)編譯會帶來巨大的潛力谒养。尤其是在它不局限于模板的時候明郭。最近达址,我們一直在使用 Prepack 來試驗 component folding沉唠,也取得了初步成效苛败。但是我們發(fā)現(xiàn)使用 class 組件會無意中鼓勵開發(fā)者使用一些讓優(yōu)化措施無效的方案罢屈。class 也給目前的工具帶來了一些問題。例如锄贷,class 不能很好的壓縮,并且會使熱重載出現(xiàn)不穩(wěn)定的情況柔昼。因此炎辨,我們想提供一個使代碼更易于優(yōu)化的 API。

為了解決這些問題乙嘀,Hook 使你在非 class 的情況下可以使用更多的 React 特性虎谢。 從概念上講低缩,React 組件一直更像是函數(shù)。而 Hook 則擁抱了函數(shù)讳推,同時也沒有犧牲 React 的精神原則银觅。Hook 提供了問題的解決方案坏为,無需學(xué)習(xí)復(fù)雜的函數(shù)式或響應(yīng)式編程技術(shù)。

示例

Hook 概覽是開始學(xué)習(xí) Hook 的不錯選擇洒忧。

三够颠、Hook符合漸進策略

總結(jié):沒有計劃從 React 中移除 class。

大部分 React 開發(fā)者會專注于開發(fā)產(chǎn)品蛉抓,而沒時間關(guān)注每一個新 API 的發(fā)布巷送。Hook 還很新矛辕,也許等到有更多示例和教程后付魔,再考慮學(xué)習(xí)或使用它們也不遲抒抬。

我們也明白向 React 添加新的原生概念的門檻非常高擦剑。我們?yōu)楹闷娴淖x者準(zhǔn)備了詳細的征求意見文檔芥颈,在文檔中用更多細節(jié)深入討論了我們推進這件事的動機爬坑,也在具體設(shè)計決策和相關(guān)先進技術(shù)上提供了額外的視角。

最重要的是售担,Hook 和現(xiàn)有代碼可以同時工作署辉,你可以漸進式地使用他們哭尝。 不用急著遷移到 Hook。我們建議避免任何“大規(guī)模重寫”逝淹,尤其是對于現(xiàn)有的桶唐、復(fù)雜的 class 組件尤泽。開始“用 Hook 的方式思考”前,需要做一些思維上的轉(zhuǎn)變醉蚁。按照我們的經(jīng)驗鬼店,最好先在新的不復(fù)雜的組件中嘗試使用 Hook妇智,并確保團隊中的每一位成員都能適應(yīng)。在你嘗試使用 Hook 后巍棱,歡迎給我們提供反饋航徙,無論好壞。

我們準(zhǔn)備讓 Hook 覆蓋所有 class 組件的使用場景杠袱,但是我們將繼續(xù)為 class 組件提供支持窝稿。在 Facebook伴榔,我們有成千上萬的組件用 class 書寫,我們完全沒有重寫它們的計劃塘安。相反耙旦,我們開始在新的代碼中同時使用 Hook 和 class萝究。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末帆竹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子险领,更是在濱河造成了極大的恐慌绢陌,老刑警劉巖熔恢,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叙淌,死亡現(xiàn)場離奇詭異愁铺,居然都是意外死亡茵乱,警方通過查閱死者的電腦和手機瓶竭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渠羞,“玉大人堵未,你說我怎么就攤上這事】榻龋” “怎么了雌芽?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵世落,是天一觀的道長。 經(jīng)常有香客問我屉佳,道長武花,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任专钉,我火速辦了婚禮跃须,結(jié)果婚禮上娃兽,老公的妹妹穿的比我還像新娘。我一直安慰自己玉雾,他們只是感情好复旬,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布驹碍。 她就那樣靜靜地躺著凡恍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嚼酝。 梳的紋絲不亂的頭發(fā)上闽巩,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天涎跨,我揣著相機與錄音,去河邊找鬼隅很。 笑死,一個胖子當(dāng)著我的面吹牛屋彪,可吹牛的內(nèi)容都是我干的撼班。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼砰嘁,長吁一口氣:“原來是場噩夢啊……” “哼矮湘!你這毒婦竟也來了口糕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤秀撇,失蹤者是張志新(化名)和其女友劉穎向族,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再扭,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡夜矗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年罢荡,在試婚紗的時候發(fā)現(xiàn)自己被綠了对扶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡惧笛,死狀恐怖逞泄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情各谚,我是刑警寧澤昌渤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布憔四,位于F島的核電站,受9級特大地震影響潜支,放射性物質(zhì)發(fā)生泄漏柿汛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一项玛、第九天 我趴在偏房一處隱蔽的房頂上張望弱判。 院中可真熱鬧,春花似錦、人聲如沸净刮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽困介。三九已至蘸际,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粮彤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工屿良, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惫周,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓喷橙,卻偏偏與公主長得像登舞,于是被迫代替她去往敵國和親逊躁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

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

  • Hook 是 React 16.8 的新增特性囚戚。它可以讓你在不編寫 class 的情況下使用 state 以及其他...
    歐雷_99f3閱讀 116評論 0 0
  • 作為一個合格的開發(fā)者驰坊,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理拳芙;不要只滿足于自己的程序...
    六個周閱讀 8,428評論 1 33
  • 主要介紹 useState useEffect useReducer useContext 用法 你還在為...
    叫我蘇軾好嗎閱讀 27,404評論 3 41
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過程中的一些閱讀筆記睹限,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,813評論 1 18
  • 3. JSX JSX是對JavaScript語言的一個擴展語法羡疗, 用于生產(chǎn)React“元素”叨恨,建議在描述UI的時候...
    pixels閱讀 2,810評論 0 24