Taro 项目拆分到多个分包后分包之间的redux状态共享

513 阅读4分钟

1、回顾上篇

Taro 项目拆分到多个分包,就是分别对==A、B页面==使用混合模式打包,步骤和把 Taro 项目作为一个完整分包一致。(Taro项目拆分到多个分包)

2、发现问题

A、B页面分别作为完整的分包,其中采用同一份状态的地方肯定不少,比如用户所属区域、用户token等,那么同步两个分包之间的状态就是重中之重的事情。

3、分布情况

项目各个包之间的关系以及状态分布大致情况如下: 状态分布 很明显多个Taro分包之间虽然采用同一种状态管理技术但其状态却是不同的,每个分包只能改变其自己的分包状态,和其兄弟分包的状态是完全隔离开的。

4、解决方案

  1. 在项目全局状态中维护一份最新的actions(收集每一个分包的action并存储到原生小程序的状态中)

收集actions

  1. 切换分包的时候将全局状态中维护的最新actions遍历执行dispatch。

熟悉redux都知道普通的action函数返回的是一个对象,类似{ type: "ADD", data: 10 },那么所有的分包想改变自身状态都需要通过dispatch(action), 那么收集并维护一份最新的actions数组并在切换分包的时候去遍历执行所有的action,就可以实现同步分包之间的状态,大体的思路就是如此。 细想后又会冒出以下几个问题:

  • 如何在dispatch执行的时候收集这个action?

  • 如何将收集到的action保存至全局状态?

  • 如何知晓当下操作时分包之间的切换?又是哪两个分包之间的切换?

  • 频繁切换分包的性能问题如何?

  • and so on ...

  1. 如何在dispatch执行的时候去收集这个action? 首先想弄明白这个问题需要弄清楚redux的整体过程,具体流程如下: redux流程 关注更新时的状态变化:
  • dispatch 一个 action 到 Redux store。
  • store 用之前的 state 和当前的 action 再次运行 reducer 函数,并将返回值保存为新的 state。 在这个流程中能收集action的步骤只能是在dispatch中。通过redux的中间件可以拿到当前的action,也就可以执行收集操作。中间件流程如下:中间件流程
  • 中间件的执行原理和koa中间件的执行原理类似,但是不是洋葱型的,而是半个洋葱,因为redux是单向执行的,走过去就完事了。就是将原来的dispatch函数封装处理后的形成新的dispatch函数,每一个中间件执行的操作都封装在新的dispatch函数中了。

通过中间件额外执行收集action的操作来解决第一个问题

  1. 如何将收集到的action保存至全局状态?

首先利用Taro.getApp()获取小程序全局唯一App对象。 方案一:将收集到的action对象无脑push到App对象的actions数组中,切换分包时候执行保存的所有action,执行完后清空actions数组。 方案二:将收集到的action对象保存到App对象的actions数组中,若已存在同类型action则直接替换,切换分包时候执行保存的所有action,无需清空actions。(不适用action类似自增功能,只适用于替换功能,相当于每一个action即最新的state) 方案三:结合以上两中方案进行优化,首先将类似自增这样的action的type声明到一个数组中,收集到的当前action进行判断是否是声明数组中的类型,若是则执行方案一,无脑push到全局actions中,若不是则先进行判断其action是否已经在全局actions中存在,若存在则删除存在的action,再将当前新的action存进全局actions的末尾,若不存在则直接将新的action存进全局actions的末尾。

  1. 如何知晓当下操作时分包之间的切换?又是哪两个分包之间的切换?

通过wx.onAppRoute在全局监听路由的变化,若命中路由变化条件,则通过全局eventBus去通知某个分包执行dispatch所有action操作。同时需要在每一个分包中写入具体的监听事件。

  1. 频繁切换分包的性能问题如何?

切换分包会遍历全局actions数组从而执行多次dispatch(action),每次执行dispatch会导致页面重新渲染吗?答案是不会。dispatch是同步的,react批处理的机制,为了将同一上下文中触发的更新合并为一个更新。

5、源码

项目地址:分包共享redux状态demo

6、结论

以上为本人对分包之间的redux状态共享的初探沉淀。