秦子實


摘要:在企業中臺等復雜交互場景的網頁應用中,基于JSP、ASP等模板技術的頁應用一直存在著拓展性差、修改維護困難、調試效率低下等問題。因此,對于企業中臺等復雜交互場景,需要一種能夠完全獨立于后端復雜網頁應用開發方法,方法應完全基于REST APl,且具備良好的拓展性,各功間能耦合性低,便于后期的迭代及維護。該文將以React框架為例,通過Redux控制數據狀態以代替傳統基于模板的網頁開發,給出一種新的獨立復雜交互式前端的開發方法。
關鍵詞:前端;JavaScript;React;Redux
中圖分類號:TP393 文獻標識碼:A
文章編號:1009-3044(2020)08-0254-02
1 概述
隨著企業業務的不斷擴展,企業中臺網頁應用需要展示的報表數量越來越多,在網頁上進行的數據操作越來越復雜。傳統基于模板的網頁開發(如JSP、ASP等)越來越難以應付這些復雜功能,基于模板的網頁應用由于HTML結構以及表單提交機制等原因,不可避免地會出現頁面代碼臃腫,數據交換冗余較大。這不僅會占用客戶端瀏覽器資源導致加載緩慢.也會在請求/提交數據時大量消耗服務器資源處理無用數據。
前端框架日趨成熟,更多的企業中臺網頁應用從原來的模板開發,轉移到基于如React或Vue等框架的JavaScript前端網頁應用。相較于模板技術,前端應用框架的核心在于狀態管理。本文以React框架為例,介紹使用Redux庫進行前端應用狀態管理,以實現具有良好擴展性、方便修改迭代、易于調試維護的獨立前端應用的實現。
2 Redux技術簡介
Redux產生的原因,是為了應對功能復雜的JavaScript單頁應用,比如在企業中臺應用里,我們希望在同一個頁面上展示大量數據,生成統計圖形和報表,同時也希望操作、處理這些數據,使得數據實時的更新至服務器,并直接將更新結果顯示在網頁上。傳統的模板式網頁開發可能就需要大量的表單提交,或是采用大量各不相同的Ajax請求,這不論對于前端的網頁渲染,還是后端的API管理,都是非常繁雜的工作,且調試環境復雜,不易定位問題。
對于這種復雜的網頁應用,Redux充分利用React等框架基于狀態(state)的頁面渲染機制,對應用數據狀態進行集中的、簡潔的管理。同時,Redux基于函數式編程的思想,使用冪等操作,加強了React等框架的狀態控制,使得網頁應用的行為變得更容易追蹤、調試及后期功能拓展。
使用Redux管理應用數據狀態,無須引入額外工具或庫,僅使用JavaScript自身的JSON數據結構以及普通的函數實現,Redux庫本身僅有2k,利于應用打包和發布。Redux在使用中需要注意三個原則:
1)應用數據狀態的唯一陛,即一個網頁應用有且僅有一個狀態對象。該原則不僅使得前后端數據交換更為簡潔,也能夠大幅降低應用調試難度,有利于持續跟蹤應用狀態,加速開發流程。
2)應用數據狀態是只讀對象,即只能夠通過發送動作(dis-patch actions)來改變該對象。該原則意味著無論應用界面的改變或是后端返回的請求都無法直接改變該狀態對象,任何對狀態改變的期望都必須通過發送一個用于改變狀態的動作來實現。如此一來,Redux通過嚴格的依次執行各個動作,實現了狀態變更的集中化管理,也同時實現了狀態的跟蹤、序列化、存儲,方便了之后的調試和測試。
3)使用冪等函數改變狀態,即使用純reducer函數改變狀態。所謂冪等操作,指于狀態無關的數據操作,即無論應用當前處于什么狀態,對同樣的輸入,一定會得到同樣的輸出。re-ducer函數的輸入為原狀態和動作,輸出為新狀態。這種設計極大地增加了應用的拓展性,隨著應用功能的復雜,reducer函數可以由原來的一個操作整個狀態,逐漸細分為多個分別操作狀態樹的各個部分。此外,因為reducer是純粹的冪等函數,我們可以輕松地控制各reducer的執行順序、傳遞額外數據或是進行函數復用(如最常見的分頁操作)。
3 Redux數據狀態控制
本文以React框架為例,使用Redux對React應用的數據狀態進行管理。Redux的數據狀態流程如圖1所示。
3.1 存儲及狀態對象
網頁應用的所有數據均維護在一個存儲(store)中,這個存儲就是數據的容器:
想要獲取當前的數據,就要對存儲進行快照,返回的快照就是應用當前的狀態(state):
狀態是一個普通的JavaScript對象,用戶能夠接觸到的視圖完全取決于狀態,在Redux中,狀態對象到視圖呈現是冪等操作,即一個確定的狀態呈現一個確定的視圖,而一個確定的視圖能夠推出一個確定的狀態,如圖l中的S1過程。
3.2 動作對象
狀態的變化能夠引起視圖的變化,在Redux中,為了保證狀態的一致性,狀態不能被直接修改,僅能夠通過發送動作(ac-tion)對象來變更。動作是一個普通JavaScript對象,其中僅'type'屬性是必須的,表示動作的名稱,其他屬性均可自定義。例如,向視圖中的一個表格添加一行數據:
動作對象通常由視圖發出,也就是用戶交在視圖上的操作期望引起狀態改變,比如在視圖的表格中點擊“增行”插入新的數據,即圖l中的E-AI-A2過程:由視圖產生交互事件E(Event),進而發送一個動作對象A1。此外,服務端返回的數據也可以通過發送動作對象引起狀態變化,比如視圖定期請求服務器獲取最新的表格數據,服務器返回并渲染在視圖中,即圖1中的req-res-A2過程。
視圖和服務端要進行多少操作,就需要產生有多少動作對象,我們通常會編寫一個函數用于快捷的生成這些動作,這個函數也稱作動作生成器(action creator):