淺嘗Hook

Hook 是 React 16.8 的新增特性逐抑。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性裆装。
官方demo

import React, { useState } from 'react';

function Example() {
  // 聲明一個(gè)新的叫做 “count” 的 state 變量
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

動(dòng)機(jī)

Hook 解決了我們五年來(lái)編寫和維護(hù)成千上萬(wàn)的組件時(shí)遇到的各種各樣看起來(lái)不相關(guān)的問(wèn)題溜族。無(wú)論你正在學(xué)習(xí) React浓体,或每天使用,或者更愿嘗試另一個(gè)和 React 有相似組件模型的框架,你都可能對(duì)這些問(wèn)題似曾相識(shí)助析。

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

React 沒(méi)有提供將可復(fù)用性行為“附加”到組件的途徑(例如犀被,把組件連接到 store)。如果你使用過(guò) React 一段時(shí)間外冀,你也許會(huì)熟悉一些解決此類問(wèn)題的方案寡键,比如 render props高階組件。但是這類方案需要重新組織你的組件結(jié)構(gòu)雪隧,這可能會(huì)很麻煩西轩,使你的代碼難以理解。如果你在 React DevTools 中觀察過(guò) React 應(yīng)用脑沿,你會(huì)發(fā)現(xiàn)由 providers遭商,consumers,高階組件捅伤,render props 等其他抽象層組成的組件會(huì)形成“嵌套地獄”。盡管我們可以在 DevTools 過(guò)濾掉它們巫玻,但這說(shuō)明了一個(gè)更深層次的問(wèn)題:React 需要為共享狀態(tài)邏輯提供更好的原生途徑丛忆。

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

具體將在自定義 Hook 中對(duì)此展開(kāi)更多討論诗力。

復(fù)雜組件變得難以理解

我們經(jīng)常維護(hù)一些組件凰浮,組件起初很簡(jiǎn)單,但是逐漸會(huì)被狀態(tài)邏輯和副作用充斥苇本。每個(gè)生命周期常常包含一些不相關(guān)的邏輯袜茧。例如,組件常常在 componentDidMountcomponentDidUpdate 中獲取數(shù)據(jù)瓣窄。但是笛厦,同一個(gè) componentDidMount 中可能也包含很多其它的邏輯,如設(shè)置事件監(jiān)聽(tīng)俺夕,而之后需在 componentWillUnmount 中清除裳凸。相互關(guān)聯(lián)且需要對(duì)照修改的代碼被進(jìn)行了拆分,而完全不相關(guān)的代碼卻在同一個(gè)方法中組合在一起劝贸。如此很容易產(chǎn)生 bug姨谷,并且導(dǎo)致邏輯不一致。

在多數(shù)情況下映九,不可能將組件拆分為更小的粒度梦湘,因?yàn)闋顟B(tài)邏輯無(wú)處不在。這也給測(cè)試帶來(lái)了一定挑戰(zhàn)。同時(shí)践叠,這也是很多人將 React 與狀態(tài)管理庫(kù)結(jié)合使用的原因之一言缤。但是,這往往會(huì)引入了很多抽象概念禁灼,需要你在不同的文件之間來(lái)回切換管挟,使得復(fù)用變得更加困難。

為了解決這個(gè)問(wèn)題弄捕,Hook 將組件中相互關(guān)聯(lián)的部分拆分成更小的函數(shù)(比如設(shè)置訂閱或請(qǐng)求數(shù)據(jù))僻孝,而并非強(qiáng)制按照生命周期劃分。你還可以使用 reducer 來(lái)管理組件的內(nèi)部狀態(tài)守谓,使其更加可預(yù)測(cè)穿铆。

我們將在使用 Effect Hook 中對(duì)此展開(kāi)更多討論。

難以理解的 class

除了代碼復(fù)用和代碼管理會(huì)遇到困難外斋荞,我們還發(fā)現(xiàn) class 是學(xué)習(xí) React 的一大屏障荞雏。你必須去理解 JavaScript 中 this 的工作方式,這與其他語(yǔ)言存在巨大差異平酿。還不能忘記綁定事件處理器凤优。沒(méi)有穩(wěn)定的語(yǔ)法提案,這些代碼非常冗余蜈彼。大家可以很好地理解 props筑辨,state 和自頂向下的數(shù)據(jù)流,但對(duì) class 卻一籌莫展幸逆。即便在有經(jīng)驗(yàn)的 React 開(kāi)發(fā)者之間棍辕,對(duì)于函數(shù)組件與 class 組件的差異也存在分歧,甚至還要區(qū)分兩種組件的使用場(chǎng)景还绘。

另外楚昭,React 已經(jīng)發(fā)布五年了,我們希望它能在下一個(gè)五年也與時(shí)俱進(jìn)拍顷。就像 Svelte哪替,AngularGlimmer等其它的庫(kù)展示的那樣菇怀,組件預(yù)編譯會(huì)帶來(lái)巨大的潛力凭舶。尤其是在它不局限于模板的時(shí)候。最近爱沟,我們一直在使用 Prepack 來(lái)試驗(yàn) component folding帅霜,也取得了初步成效。但是我們發(fā)現(xiàn)使用 class 組件會(huì)無(wú)意中鼓勵(lì)開(kāi)發(fā)者使用一些讓優(yōu)化措施無(wú)效的方案呼伸。class 也給目前的工具帶來(lái)了一些問(wèn)題身冀。例如钝尸,class 不能很好的壓縮,并且會(huì)使熱重載出現(xiàn)不穩(wěn)定的情況搂根。因此珍促,我們想提供一個(gè)使代碼更易于優(yōu)化的 API。

為了解決這些問(wèn)題剩愧,Hook 使你在非 class 的情況下可以使用更多的 React 特性猪叙。 從概念上講,React 組件一直更像是函數(shù)仁卷。而 Hook 則擁抱了函數(shù)穴翩,同時(shí)也沒(méi)有犧牲 React 的精神原則。Hook 提供了問(wèn)題的解決方案锦积,無(wú)需學(xué)習(xí)復(fù)雜的函數(shù)式或響應(yīng)式編程技術(shù)芒帕。

示例

Hook 概覽是開(kāi)始學(xué)習(xí) Hook 的不錯(cuò)選擇。

漸進(jìn)策略

總結(jié):沒(méi)有計(jì)劃從 React 中移除 class丰介。

大部分 React 開(kāi)發(fā)者會(huì)專注于開(kāi)發(fā)產(chǎn)品背蟆,而沒(méi)時(shí)間關(guān)注每一個(gè)新 API 的發(fā)布。Hook 還很新哮幢,也許等到有更多示例和教程后淆储,再考慮學(xué)習(xí)或使用它們也不遲。

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

最重要的是,Hook 和現(xiàn)有代碼可以同時(shí)工作舔株,你可以漸進(jìn)式地使用他們莺琳。 不用急著遷移到 Hook。我們建議避免任何“大規(guī)模重寫”载慈,尤其是對(duì)于現(xiàn)有的惭等、復(fù)雜的 class 組件。開(kāi)始“用 Hook 的方式思考”前办铡,需要做一些思維上的轉(zhuǎn)變辞做。按照我們的經(jīng)驗(yàn),最好先在新的不復(fù)雜的組件中嘗試使用 Hook寡具,并確保團(tuán)隊(duì)中的每一位成員都能適應(yīng)秤茅。在你嘗試使用 Hook 后,歡迎給我們提供反饋童叠,無(wú)論好壞框喳。

我們準(zhǔn)備讓 Hook 覆蓋所有 class 組件的使用場(chǎng)景,但是我們將繼續(xù)為 class 組件提供支持。在 Facebook五垮,我們有成千上萬(wàn)的組件用 class 書寫乍惊,我們完全沒(méi)有重寫它們的計(jì)劃市埋。相反佩耳,我們開(kāi)始在新的代碼中同時(shí)使用 Hook 和 class。

FAQ

我們準(zhǔn)備了 Hooks FAQ 來(lái)解答最常見(jiàn)的關(guān)于 Hook 的問(wèn)題书幕。

下一步

在本章節(jié)的最后匙监,你應(yīng)該對(duì) Hook 能解決什么問(wèn)題有了粗略的理解凡橱,但可能還有許多細(xì)節(jié)不清楚。不要擔(dān)心亭姥!讓我們?nèi)?a target="_blank">下一章節(jié)通過(guò)例子學(xué)習(xí) Hook稼钩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市达罗,隨后出現(xiàn)的幾起案子坝撑,更是在濱河造成了極大的恐慌,老刑警劉巖粮揉,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巡李,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡扶认,警方通過(guò)查閱死者的電腦和手機(jī)侨拦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)辐宾,“玉大人狱从,你說(shuō)我怎么就攤上這事〉疲” “怎么了季研?”我有些...
    開(kāi)封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)誉察。 經(jīng)常有香客問(wèn)我与涡,道長(zhǎng),這世上最難降的妖魔是什么持偏? 我笑而不...
    開(kāi)封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任驼卖,我火速辦了婚禮,結(jié)果婚禮上鸿秆,老公的妹妹穿的比我還像新娘款慨。我一直安慰自己,他們只是感情好谬莹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布檩奠。 她就那樣靜靜地躺著桩了,像睡著了一般。 火紅的嫁衣襯著肌膚如雪埠戳。 梳的紋絲不亂的頭發(fā)上井誉,一...
    開(kāi)封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音整胃,去河邊找鬼颗圣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛屁使,可吹牛的內(nèi)容都是我干的在岂。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蛮寂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蔽午!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起酬蹋,我...
    開(kāi)封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤及老,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后范抓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體骄恶,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年匕垫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了僧鲁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡象泵,死狀恐怖寞秃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情单芜,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布犁柜,位于F島的核電站洲鸠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏馋缅。R本人自食惡果不足惜扒腕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望萤悴。 院中可真熱鬧瘾腰,春花似錦、人聲如沸覆履。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至栖雾,卻和暖如春楞抡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背析藕。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工召廷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人账胧。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓竞慢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親治泥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子筹煮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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