體驗 @tanstack/router 發現它不簡單 —— 幫我給 Next.js ‘祛魅’了。
此前我覺得 Next.js 非常成熟了,從 fullstack 的設計上,無能出其右了。但閱讀 @tanstack/router 的文檔,感覺世界依然很開闊。
文檔中給了 stackblitz 例子,非常全面。但直到我真的實踐項目代碼和頁面的時候,想找最佳實踐範例的時候,才知道它提供的例子是多好。
上次感受到 example 好,是 n 年前看到 webpack 官方倉庫有 examples,next.js 有 examples,plasmo 有 examples,有非常多的 with-xxx 示例。
這次感覺到 example 好,是因為一直以來想找一些 realworld 的項目,具體實踐。其一滿足平時接收到的說法,各種場景都很常見,那就應該有一個例子可以收束全部的場景。
開始寫代碼遇到的困難#
我開始實踐,感受到的困難是,兩個技術結合的時候,似乎非常靈活,我選不出來最好的方式,用最基礎的方式結合了(在一個文件中,把相應的膠水代碼都粘好),接下來好想還有無盡的優化,比如要頻繁使用的代碼抽取公共 file,保持單例複用。有多了幾層傳入參數的位置,要做好劃分。這就成了我事先想不到的,或者,接觸到之後,會陷入其中的工作。最期望找到一個最佳實踐。
現在,我還沒看完就感受到的最佳實踐它來了。
一起來看 Ktichen Sink Example#
功能體驗#
-
一個演示參數的控制面板,深得我心。全都是直接影響腳手架,頁面切換表現的關鍵參數。
-
場景列表:
- 基礎:登錄 / 未登錄,layout,lazy,nested router
- 隱藏基礎:url 參數對應的 store 邏輯;param 序列化;param -> deps -> loader 處理
- 交互:路由的 loader pending 狀態處理;Created 狀態處理
- 深層交互:鏈接預加載
代碼細節 —— 技術點結合方式#
閱讀一遍,類似把官方文檔的內容複述一遍,但內容是自己創建和表達的。不省略,不直接複制,就是有收獲的。
- auth
加載順序 - beforeLoad 中添加跳轉邏輯;
添加 context, 用於依賴注入,避免子路由中頻繁導入,所以 context 也要克制,避免加入巨大的 chunk;
從 api 設計上,事件周期環節分層,根據要兼顧的場景拆分。理論上可自由無限擴充,但極為克制且成功的,才能成為能流行的框架
遺留問題:login 按鈕的 loading 如何處理?同樣還有 logout 的?登錄成功後,調用 invalidate,依賴 loader 中檢測已經登錄,跳轉到登錄後默認界面的邏輯
- layout
- 基於文件名或文件夾 _layout 前綴,或 _layout.route.tsx
- 此處,把常規的 ``==`./index`細分了,變為 [`` == `/route` | `../[文件夾同名文件]` , `/` == `/index` ]
- data-loader with @tanstack/query
我的簡單設想 —— 在組件代碼中,添加 useQuery, 與常規使用無異。
打破設想 —— 自帶的 loader 與這個不相符,也無法把 query 的狀態傳到當前的 router 中,另外 context 是一個統一的 inject 位置,沒有給每一層 router 劃分獨立空間。
kitchen-sink 的做法:將 queryClient 放置到 context 中,loader 中使用 queryClient 的 ensureQueryData,組件中,使用 useQuery 設置相同的 option,獲取同一份數據。 - data-loader 的狀態處理
提供了<MatchRoute />
組件,有點兒不符合我的直覺。其參數是 filter 參數,導致我以為是 settle 參數。我的習慣一般是使用 useXXX 判斷。但這裡提供了組件,通過函數式的 children 方式響應變化。 - dataMutation within @tanstack/query
與 @tanstack/query 的 useMutation 一致,沒有結合使用的新用法。
第一遍已經讀完。祛魅一部分。現在,實踐一部分,看看是否有不清楚的。如果有,就再繼續記錄。