使用 BlueprintJS + React Hook API + Typescript 打造後台系統高效能 Table元件

Peace Pan
萬達寵物系統發展部
4 min readJul 3, 2019

前言

想要使用 React 打造後台系統時,可能會選擇使用以下幾種框架來加快開發速度,

  1. React Bootstrap
  2. Semantic UI
  3. Metarial UI
  4. Ant Design
  5. BlueprintJS
  6. etc…

而由於有著大量複雜資料的需求,在這裡選擇使用 BlueprintJS 來作為後台系統的 UI 框架。

BlueprintJS 是由一家位於美國加州的大數據公司 Palantir 為大數據所打造的一套 UI 框架,打著用大數據預測未來的公司,而 Palantir 的意思是《魔戒》中能看到未來的水晶球。

你可能沒有聽過 BlueprintJS 但總該聽過 Typescript ,而 TSLint 這個 Typescript 的 Type 檢測工具正是 Palantir 這家公司團隊所開發的。TSLint in 2019。因此 BlueprintJS 是個有著為大數據打造及對 Typescript 的 lint rule 有深厚基礎的老爸所誕生的兒子。

正題

資料瀏覽性質高的後台系統最主要的資料瀏覽元件就是 Table ,因此我們就以 BlueprintJS 所設計的 Table 與 React Hook API 來包裝成我們所需要的 React Function Component.

Table 主要顯示的資料不外乎就是 Rows 與 Columns ,而 BlueprintJS 的 Table 設計與其他框架的 Table 的設計概念不太一樣,資料不是以 Row 的角度來做渲染,而是以 Column 與 Cell 的角度,藉由多個客製化的 Renderer 來優化整體的渲染效果,讓 Table 每一個 Cell 做到最小化的渲染。

這樣說可能有點抽象,一般來說,我們要顯示 Rows 的資料可能會把整個 Rows 的資料丟到 Table 元件裡,然後利用迴圈把整個 Rows 資料渲染出來,而每當 Rows 資料有變更時,整個迴圈再重跑一次再做渲染,因此當 Rows 的資料超過上百筆或上千筆時,重新渲染的代價非常高。

從官方給的展示代碼來看

從中可以看出幾點

  1. 傳給 Table 的 props 並不需要 Rows 資料,只需告訴 Table 需要幾列資料
  2. 可以決定要顯示幾個 Column 資料
  3. CellRenderer 有兩個參數 rowIndex 與 columnIndex (文件中有說明),兩者搭配就可以取得要顯示 Cell 資料

這表示說 BlueprintJS 的 Table 元件內並不需要維護複雜的 Rows 資料,只要使用各種 Renderer 來告訴元件如何顯示資料就行了。

那麼就接著根據官方文件給的資訊,來打造一個簡單的 Table 元件。

上面的代碼中,我使用了三個 Renderer ,分別是 cellRenderer, headerNameRenderer, columnHeaderCellRenderer 每個各自負責要渲染的資料,與資料管理沒有任何關聯;使用 React.memo 將元件包裝以及對每個Cell 都給予一個 Key 來優化效能。

接著這邊使用 NextJS 建立一個簡單頁面及一些資料來顯示 Table 內容,然後使用一個按鈕來點擊,隨機更新 Rows 的資料,再使用 React devtool 來查看元件更新的狀況。

結論

當 Rows 的資料更新時,只有資料變更的 Cell 會被重新渲染,這確實達到了我們期望的結果,在大量的 Rows 資料變更時,可以最小量化畫面的更新,而不會整個 Table 的 Rows 與 Columns 都重新的渲染。

比較遺憾的是,Columns 的 Header 在 Cell 渲染時也會重新渲染,目前尚未從官方 Github 中找出相關的 Solution ,若您有相關的意見或建議,還懇請請提出指教。

--

--