組件
組件是 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 組件來搭建,可是其中仍是有不少邏輯,咱們是沒法避免的。
-
page,pageSize管理
-
page,pageSize 變化時從新進行異步請求
-
篩選條件變化時,重置 page,並從新請求數據
-
異步請求的 loading 處理
-
異步請求的競態處理
-
組件卸載時丟棄進行中的異步請求(不少人一般不處理,在某些狀況會報警告)
上面的邏輯,咱們在幾乎全部的 table 頁是必需要處理的,想一想均可怕。useAntdTable 至少封裝了上面 6 個邏輯,
一行代碼封裝全部邏輯,列表頁開發從未變得如此簡單。
const { tableProps } = useAntdTable(asyncFn);
const columns = [];
return (
<Table columns={columns} rowKey="id" {...tableProps} />
)
複製代碼
useSearch
-
防抖
-
異步請求的 loading 處理
-
異步請求的請求時序控制
-
組件卸載時取消防抖及異步請求等邏輯
const { data, loading, onChange } = useSearch(asyncFn);
<Select
onSearch={onChange}
loading={loading}
>
{data.map((item)=><Option />)}
</Select>
複製代碼
更多的 Custom Hooks
固然,咱們還有更多極大提效的 Custom Hooks,你能想象
不用寫一行邏輯,就能實現異步 loadmore 功能嗎?(
useLoadMore)
基礎 Hooks
react-use 應該是目前發展最好的 Hooks 庫,可是咱們正在逐漸放棄它,最大的緣由是版本升級太快,你能想象幾個月以前我項目中用的是 v9,如今已是 v13 了嗎?我已經不知道怎麼去升級了。
爲了解決這個問題,@umijs/hooks 也沉澱了平常工做中頻繁使用的基礎 Hooks,包括經常使用的 useAsync,useDebounce,useBoolean,useMouse 等等,而且還在不斷髮展。也許只用 umi hooks 就夠了。
寫在最後
umi hooks 讓中臺開發變得如此簡單,我能想象,不久的未來,中臺開發能夠不用寫一行邏輯,這也是咱們爲之奮鬥的目標。
同時,但願更多的人蔘與進來,你能夠提供好的 idea,也能夠將平常封裝的 Hooks 貢獻上來,讓 umi hooks 更加豐滿,讓更多的人收益。