[ 一起學React系列 -- 6 ] 祕術之時間旅行-1

標題看起來挺新穎的,筆者都覺得很高大上是不是哈哈...

拋轉

時間旅行在生活中是一個非常吸引人的概念,雖然現在無法實現但說不定未來的某天就實現了!然後就穿梭會過去殺掉小時候的自己然後就開始懵逼自己是誰類似的狗血劇情...那麼問題來了,我們能活到那個時候嗎?這個問題咱們暫且放一下,畢竟今天不是聊科技談科幻的啊!!!

引玉

雖說生活中我們無法實現時間旅行,但是在React世界中我們卻可以輕而易舉得實現時間旅行,當然也不僅僅限於React,所有存在狀態的組件都可以實現時間旅行。說了那麼多時間旅行,那麼時間旅行到底是什麼東西?本篇以React爲例,不討論其他框架。所謂的時間旅行從廣義上來說無非就是三個動作:回到過去、進入未來、回到現在,這個無論是從現實還是前端技術來說都是可靠的。對於React某個組件來說,我們可以讓它退回到過去的某個點或者回到最新的狀態,這就是時間旅行的基本表現形式。單從React技術棧來說,時間旅行不是一門技術而是一個思想套路。爲什麼說是一個思想套路?我們繼續說...

鋪墊

看我筆者前面關於State的博文的朋友都知道,React組件是具有狀態(State)的,而且組件的具體表現形式(也就是組件的UI)也是狀態所決定的,一旦狀態發生改變那麼組件的表現也會發生相應變動,因爲State是組件改變的唯一依據。那麼我們是否會得到一個啓示?假使我們將組件的某個State在不同時間的值記錄下來保存在某個地方,在合適的時機拿出不同的值賦值給相應的State,那麼組件不就可以隨之改變從而實現所謂的時間旅行了嗎!!!沒錯,實際上時間旅行就是基於這個思路被開發出來的思想套路。

縱深

這個概念最早是在Redux架構中提出的,基於組件State中值的不可變性,通過對狀態的管理實現某個組件的狀態切換。當然本文不直接跳到Redux上去說時間旅行,我們暫用最簡單的State來實現組件的時間旅行。所有狀態的切換、保存、重新渲染都在一個組件中進行,爲了方便大家能看明白,筆者構思了一張圖和寫了一個例子,代碼會在文章末尾呈上,雖說是一個簡單的例子但是對於第一次接觸這個概念的朋友來說肯定是一個優秀的可以用來理解的例子。
不過先前筆者在查閱資料的過程中發現Redux文章有相關的介紹,雖然沒有直接說是時間旅行但是實現上大同小異。文檔中用三個變量來實現相關功能:

const initialState = {
  past: [],
  present: null,
  future: []
}
顧名思義:
past用來存儲相對於當前的過去的狀態;
present用來存儲當前的狀態;
future用來存儲相對於當前的未來的狀態。

假如我們點擊 Undo(撤銷)的時候先present值存到future中再將past中最後一個狀態對象取出來賦值給present,這樣就實現了文檔中撤銷的功能;假如我們點擊 Redo(返回)的時候先present值存到past中再將future中最後一個狀態對象取出來賦值給present,這樣就實現了文檔中返回的功能;如此來看,本質上還是狀態的管理。

另闢蹊徑

什麼叫另闢蹊徑?筆者看完文檔後若有所思,是不是有必要用三個變量來實現這個功能?頻繁得處理數組和賦值會不會太過麻煩?於是筆者在思考之後覺得完全可以使用兩個變量就可以實現同樣的功能:

archive = [];
currentIndex = 0;
archive變量來存儲每個時刻的狀態
currentIndex變量用來記錄當前狀態是archive中的那個狀態對象

警告:這種實現方式沒有在項目中實際使用過,只是停留在筆者的例子中,所以筆者不能完全保證能經受住項目的真實考驗!

咱們繼續說!
筆者覺得這樣實現的方式可以相對簡潔:每次我們改變組件某個狀態的時候同時將該狀態存儲在archive變量中,同時currentIndex+1;假如我們點擊了Undo或者Redo,我們只要對currentIndex進行減一或者加一就能知道需要的狀態在archive變量的哪個位置,繼而拿出來賦值給State變量不就可以實現組件UI的重新渲染了嗎!!!筆者也對此花了一個手稿圖,雖簡陋但不失優雅(emmmm....吐)
圖片描述

實例展示

筆者根據自己的思路寫出了對應的例子,由於代碼不算複雜所以就沒必要在這裏做代碼分析了,相信大家都能看得懂,所以筆者就把項目代碼放在這供大家學習參考,當然項目中也包含了下一篇所要說的基於Redux實現時間旅行的代碼,大家有興趣的可以看下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章