[ 一起学React系列 -- 6 ] 秘术之时间旅行-1

littlelittle00 2019-06-28

标题看起来挺新颖的,笔者都觉得很高大上是不是哈哈...

抛转

时间旅行在生活中是一个非常吸引人的概念,虽然现在无法实现但说不定未来的某天就实现了!然后就穿梭会过去杀掉小时候的自己然后就开始懵逼自己是谁类似的狗血剧情...那么问题来了,我们能活到那个时候吗?这个问题咱们暂且放一下,毕竟今天不是聊科技谈科幻的啊!!!

引玉

虽说生活中我们无法实现时间旅行,但是在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....吐)
[ 一起学React系列 -- 6 ] 秘术之时间旅行-1

实例展示

笔者根据自己的思路写出了对应的例子,由于代码不算复杂所以就没必要在这里做代码分析了,相信大家都能看得懂,所以笔者就把项目代码放在这供大家学习参考,当然项目中也包含了下一篇所要说的基于Redux实现时间旅行的代码,大家有兴趣的可以看下。

相关推荐