React Hooks 在螞蟻金服的實踐

組件

組件是 UI + 邏輯的複用,但邏輯複用能力等於 0。
一個 React 項目,是由無數個大大小小的組件組合而成的。在 React 的世界中,組件是一等公民。而咱們平時拆分組件的依據無非是:儘可能的複用代碼。
組件是 UI + 邏輯的複用,你不能將 UI 和邏輯拆開。好比 Antd 的 Cascader 級聯選擇 組件,內置了樣式和級聯選擇的邏輯,用戶使用的時候至關於一個黑盒,只管用就好了。可是有一個很現實的問題,當該組件的樣式不能知足咱們需求的時候,咱們須要從 0 從新實現一個組件,重寫 UI + 邏輯,哪怕邏輯真的如出一轍。組件的邏輯複用能力等於 0。我能夠想到一個可怕的事實,社區上的同類組件,大部分的邏輯都是能夠複用的,只是在樣式上有差別,但邏輯共享在社區上並無很流行。

HOC 與 Render Props

HOC 與 Render Props 能夠把邏輯抽出來複用,但並無讓邏輯複用流行起來。
固然,我上面說的不能複用有點誇張,React 提供了 HOC 與 Render Props 兩種方式來解決邏輯複用的問題。好比下面的監聽鼠標位置的邏輯,咱們就能夠經過 Render Props 來複用。
<Mouse>
  (position)=> <OurComponent />
</Mouse>複製代碼
同類邏輯包括監聽 window size,監聽 scroll 位置等等。可是咱們通常不多用 render props 來封裝邏輯,更少去和其它項目去共享邏輯。爲何呢?想一想多個邏輯複用會怎麼樣,你就知道多可怕了。
<WindowSize>
  (size)=> (
        <Mouse> (position)=> <OurComponent size={size} mouse={position}/> </Mouse> ) </WindowSize> 

複製代碼
嵌套地獄的代碼是咱們不能忍受的,同時 HOC 也存在相似的問題,這多是致使邏輯複用不能流行起來的一個重要緣由。

React Hooks

React Hooks 很好的解決了邏輯複用的問題,同時社區中誕生了一批比較好的 React Hooks 庫。
React Hooks 是今年 React 的一個重磅炸彈,在社區引發了激烈的迴響。隨着 Hooks 的誕生,咱們能夠經過 Custom Hooks 很方便的封裝邏輯,邏輯共享也成爲了潮流。好比上面的例子,咱們就能夠經過 react-use 很方便的實現。
import {useMouse, useWindowSize, useScroll} from 'react-use'

function Demo(){
  const mousePosition = useMouse();
  const windowSize = useWindowSize();
}

複製代碼
react-use 是社區中比較優秀的 Hooks 庫,封裝了不少經常使用的基礎邏輯,在平常開發中必不可少。可是隻用 react-use 就夠了嗎?顯然不是。react-use 中的 Hooks 粒度比較小,相似於工具庫。
而在中臺產品中,有不少特定的場景邏輯,須要多個 Hooks 進行組合,或者定製特定的邏輯。在螞蟻內部,有很是多的中臺應用,開發者在各自項目中沉澱了各類好用的 custom Hooks,咱們把這些好用的邏輯拿出來,建立了 @umijs/hooks ,定位爲爲中颱場景服務的 Hooks 庫。

@umijs/hooks

@umijs/hooks 是面向中臺應用場景的 Hooks 庫,封裝了中臺常見場景的邏輯,讓中臺開發變得超級簡單。@umijs/hooks 已經在螞蟻金服多個產品中落地,口碑很好,提效明顯。固然,你可能不信,口說無憑,那就用例子來講話。

useAntdTable

中臺開發中,table 頁面應該算最多的一個了,咱們通常會使用 Antd 的 Table 組件來搭建,可是其中仍是有不少邏輯,咱們是沒法避免的。
  1. page,pageSize管理
  2. page,pageSize 變化時從新進行異步請求
  3. 篩選條件變化時,重置 page,並從新請求數據
  4. 異步請求的 loading 處理
  5. 異步請求的競態處理
  6. 組件卸載時丟棄進行中的異步請求(不少人一般不處理,在某些狀況會報警告)
上面的邏輯,咱們在幾乎全部的 table 頁是必需要處理的,想一想均可怕。useAntdTable 至少封裝了上面 6 個邏輯, 一行代碼封裝全部邏輯,列表頁開發從未變得如此簡單
const { tableProps } = useAntdTable(asyncFn);
const columns = [];
return (
  <Table columns={columns} rowKey="id" {...tableProps} />
)

複製代碼

useSearch

常見的異步搜索場景,咱們通常要處理:
  1. 防抖
  2. 異步請求的 loading 處理
  3. 異步請求的請求時序控制
  4. 組件卸載時取消防抖及異步請求等邏輯
如今一切變得如此簡單:
const { data, loading, onChange } = useSearch(asyncFn);

<Select
  onSearch={onChange}
  loading={loading}
>
  {data.map((item)=><Option />)}
</Select>

複製代碼

更多的 Custom Hooks

固然,咱們還有更多極大提效的 Custom Hooks,你能想象 不用寫一行邏輯,就能實現異步 loadmore 功能嗎?( useLoadMore)



你能想象不用寫一行邏輯,就能實現動態增刪,排序的表單嗎?( useDynamicList)


各類常見場景,統統不用寫邏輯,統統不用寫邏輯。你能夠在 @umijs/hooks 發現更多好用的 Hooks。

基礎 Hooks

react-use 應該是目前發展最好的 Hooks 庫,可是咱們正在逐漸放棄它,最大的緣由是版本升級太快,你能想象幾個月以前我項目中用的是 v9,如今已是 v13 了嗎?我已經不知道怎麼去升級了。
爲了解決這個問題,@umijs/hooks 也沉澱了平常工做中頻繁使用的基礎 Hooks,包括經常使用的 useAsync,useDebounce,useBoolean,useMouse 等等,而且還在不斷髮展。也許只用 umi hooks 就夠了。

寫在最後

umi hooks 讓中臺開發變得如此簡單,我能想象,不久的未來,中臺開發能夠不用寫一行邏輯,這也是咱們爲之奮鬥的目標。
同時,但願更多的人蔘與進來,你能夠提供好的 idea,也能夠將平常封裝的 Hooks 貢獻上來,讓 umi hooks 更加豐滿,讓更多的人收益。
若是你以爲不錯,動動手指, 點個 star,鼓勵下咱們,萬分感謝!
相關文章
相關標籤/搜索