React 中後臺系統多頁籤實現 | 項目覆盤

在中後臺管理類系統中,多頁籤的需求很是廣泛,用戶經常須要在多個頁籤內跳轉,好比填寫表單時去查詢某個列表獲取一些字段信息再回到表單頁面填寫。這樣的需求在 Vue 中使用 keep-alive 便可實現,可是在 React 中,React Router 切換路由後就會卸載組件,而自己並無提供相似 keep-alive 的功能,因此實現多頁籤的功能就會變得格外困難。個人項目也遇到了一樣的問題,在 2019 年左右作了技術調研和選型,最終選擇了 react-router-cache-route,並在此基礎上實現了多頁籤的需求,並穩定運行了 2 年的時間。下面我來複盤一下此次的多頁籤改造。html

1、項目簡介

本項目是我如今所在部門的項目,是一個企業級中後臺管理系統,包括系統管理、角色權限體系、基於 Activiti 的工做流引擎等不少開箱即用的功能。項目包括先後端,後端是咱們部門自研的基於 Spring 的企業級 Java 框架,前端是 React 技術棧,當時仍是 v15 版本。React Router 仍是 v2 版本前端

項目主要對象是提供給科技部門有中後臺和流程需求的項目組,基於咱們項目提供的基線工程,能夠快速搭建工程,在此基礎上根據需求進行開發。截止到 2019 年 10 月我離開該項目組,本項目已經服務了行內近 50 個系統。vue

2、需求背景

當時的多頁籤需求仍是比較明確的,由於咱們團隊在 2013 年使用 Sea.js + JQuery 的後管類系統都早已實現了,而新的使用 React 技術棧構建的新 UI 卻丟失了這個功能,備受用戶詬病,指望多頁籤的需求十分強烈。而 Vue 使用 keep-alive 便可實現多頁籤功能,以下圖的 vue-element-admin 就是典型的多頁籤案例。react

截屏2021-03-20 下午2.11.24.png

React 多頁籤自己好實現,難點是沒有官方提供相似 Vue 的 keep-alive 功能,而使用 React Router,路由切換會直接卸載組件,致使沒法緩存,用戶的數據和行爲所以丟失了。git

社區上關於多頁籤的需求呼聲也很是高,可是如 React 社區比較出名的中後臺方案 Ant Design Pro 也不支持該功能,兩年沒看,至今仍然有不少 Issue 提出這類需求:github

截屏2021-03-20 下午3.05.02.png

偏右大佬早在 2017 年對此作出了迴應,詳見 可否提供tab切換模式 · Issue #220 · ant-design/ant-design-pro · GitHub,這個 Isuue 雖然關閉了,但這些年仍然活躍:web

截屏2021-03-20 下午3.08.11.png

看 👎 的數量就知道,用戶其實對這種回答很不買賬。再來看 2019 年偏右對這個問題的解釋,稍微具體了些:後端

截屏2021-03-20 下午3.07.53.png

這個解釋我我的並不徹底認同。首先說 「tab 模式沒法(不適合)進行 url 的分享」實際上是不成立的, url 帶路由和參數就能準確跳轉到對應頁面,這在咱們系統和 Vue 的多頁籤系統裏都是基本功能;而說瀏覽器自己有 tabs 就不須要作到網站內部,也比較片面,SPA 的頁面不開瀏覽器 tab 應該更符合 Antd 的設計價值觀:足不出戶 - Ant Design,就連最新版的 Chrome 都已經支持「羣組」功能了,讓用戶在 SPA 頁面儘可能不開瀏覽器頁籤才應該是更好的體驗設計。api

看看社區其餘人的理性分析:數組

截屏2021-03-20 下午6.09.07.png

3、方案選型

通過一番調研以後,基本的思路大概有三種:

  1. 使用 Redux,數據往 store 裏面懟,實現頁面數據的」緩存「。
  2. 改寫 React Router 源碼,切換路由不卸載,改成隱藏。
  3. 使用社區的輪子,當時選了GitHub 裏的兩個產品: React Keeperreact-router-cache-route

其實每種方案都存在一些問題,最終的選擇是使用了排除法。 第一種方案的缺點是,因爲存在大量的存量項目,並且項目自己的代碼也不少,改造侵入性比較大,不是很好的選擇。 第二種的思路和 react-router-cache-route 比較像,就不想重複造輪子了。 第三種選用開源方案其實當時也不太想選擇,別看如今這兩個項目都有 700 多 star,在當時 star 數只有幾十個並且 Issue 和 Pr 也不多,也就是用戶和貢獻者都很少,因此擔憂會有後續維護性的問題以及隱藏的暗坑。

最終同事選擇了 react-router-cache-route,但在當時在項目嘗試集成的時候,直接就報個錯,給了我同事當頭一棒,詳見這個 Issue

截屏2021-03-20 下午4.47.04.png

同事找到我來排查問題,通過定位,發現是 React 16 的一個 Breaking Change 致使的,從 React 16 版本開始, React 組件能夠返回數組了,而 React 15 不行,詳見我提交的這個 PR
截屏2021-03-20 下午4.48.03.png

解決了 react-router-cache-route 在 React 15 版本報錯問題以後,接下來的工做就是實現頁籤的 UI 和打開關閉的邏輯了,注意關閉須要調用 react-router-cache-route 的卸載緩存 API。

4、還存在什麼問題

項目組深度使用 react-router-cache-route 兩年時間了,期間因爲 React 和 React Router 版本迭代也出現過一些問題,好在 react-router-cache-route 的做者一直保持更新,解決了不少棘手的問題。

但目前總結起來仍然存在兩個問題,一個是嵌套的 Cache Route 內部 Route 沒法清除緩存問題,剛纔看了一下,這個問題終於有了解,詳見 Issue #64

截屏2021-03-20 下午5.29.09.png

但這個問題大約 1 年時間纔有解

還有一個問題,這個其實不是 react-router-cache-route 的問題。咱們在多頁籤的迭代中增長了相同組件多開功能,這個場景比較常見,好比列表頁點擊連接跳轉到表單頁,能夠同時打開多個表單,這樣在不使用 Redux 是沒有什麼問題,可是一旦數據存在 Redux 中,多開組件就會有問題,顯示的始終是 store 中最新的數據,要解決這個問題,須要重構 Redux 相關邏輯,比較麻煩。

5、如今 React 多頁籤方案有啥新進展嗎

有很長時間沒關注了,這兩天覆盤看了看相關 Issue,發現又出現了一些新的輪子,沒有驗證過,先放在下面供同窗們參考。若是想要實現多頁籤功能的同窗,仍是推薦使用 react-router-cache-route,畢竟咱們已經穩定使用兩年多了,沒有太大問題。

你們選擇的時候能夠考察其原理,star 數,Issue 數,PR 數等,固然,也能夠看看他們實現的原理,學習一下這塊的思路也是不錯的。

6、結語

中後臺類系統多頁籤的需求應該是不少的,React 技術棧目前尚未大一統的解決方案,目前是輪子齊飛的狀態。但願本文的經驗可以幫助到你們,少走彎路。


本文正在參與「掘金 2021 春招闖關活動」, 點擊查看 活動詳情

相關文章
相關標籤/搜索