187 - 《蚂蚁中后台数据流的新选型》

发布于 2022年9月16日

我们的数据流方案要做一次迭代,以下是做了些调研后的整理,暂未包含和 Umi 框架结合的部分。

背景知识:数据流 2022

先说结论:目前个人的倾向是,基于 Valtio 浅封一个数据流方案集成到 Umi 中。

为啥是 valtio?

valtio 的特点是外部多 Store + 基于 Proxy。1)个人用不惯 jotai 和 recoil 这种 react 内部原子化的数据流方案,感觉和被 redux 培养起来的心智模型有冲突,所以会更倾向于外部 Store 一些,2)由于场景是中后台,对于兼容性的容忍度比较高,比如不用兼容 IE11,所以完全可以用基于 Proxy 的数据流方案,这类数据流方案在更新数据和读取数据时都更简单。

为啥不是 zustand?

zustand 和 valtio 是同一个作者写的,功能覆盖上其实比较类似,最大的区别是 valtio 基于 proxy 而 zustand 不是。个人有几个方面的考虑,1)更新数据,2)读取数据,3)类型提示。

更新数据的方式更符合人性,比如可以直接 state.todos['321'].completed = true,而不用 setState(todos => ({ …todos, 321: { …todos['321'], completed: true } }))。当然,这一点非 proxy 方案可基于 immer 实现和 proxy 方案类似的操作。

读取数据默认高性能,无需 selector。非 proxy 方案比如 react-redux 和 zustand 为了性能优化,避免不必要的 re-render,通常会通过 selector 选择 store 的一部分,这会带来不必要的心智负担。基于 Proxy 的方案是响应式的,无需 selector,默认高性能。

类型提示的差异主要在扩展上。valtio 用的是组合式,zustand 用的是 middleware。没具体试过 zustand 的 middleware,但个人理解,理论上 middleware 的类型提示没有 valtio 友好。比如 valtio 的 proxyWithHistory 会把数据结构改成 { value, history, redo, undo, … } 这种,在类型提示上可以完美衔接。

为啥要封一层而不直接用?

有几个考虑。

1、valtio 未来肯定会迭代,加一层封装能抹平大版本更新导致的可能的 break change,方便做应用治理

2、调整实现。比如包括,1)约束接口;2)封装更多符合蚂蚁需求的扩展,比如 persistant storage 扩展、log 扩展、auto loading state 扩展等;3)支持全局生效的扩展。

3、便于和框架结合,在使用、性能等方面都有更优表现,没具体展开想过,目前想到的比如基于路由的按需、store 微生成器、配置式的扩展、和请求方案的结合等

valtio 的功能如何?

数据流方案应该关注啥? 整理之后发现还是有不少的。比如心智模型、读取数据、写入数据、数据推导、异步 Action、渲染性能优化、Suspense 并发模式支持、SSR 支持、React 之外访问、组件封装、瞬时更新、插件中间件扩展、Redux DevTools 支持、兼容性、多实例和单实例、数据序列化能力、同步/异步更新、内存管理、测试、包尺寸等。(还有啥?)大部分数据流方案都考虑了这些点,区别是实现方式和使用体验上的差异。

基本用法

极其简单。

// 1、定义数据
const state = proxy({ count: 0 });
// 2、使用数据
const snap = useSnapshot(state);
snap.count;
// 3、更新数据
state.count += 1;

React 外访问

天然支持。

const state = proxy({ count: 0 });
state.count;
state.count += 1;

数据推导

const state = proxyWithComputed({
  count: 0,
}, {
  double: snap => snap * 2,
});

Action 和异步 Action

两种用法,可以和 state 放一起,也可以分开。

// 方法一:放一起
const state = proxy({
  count: 0,
  actions: {
	  add() {
	    // 注意这里别用 this.count,基于 snap 调用时会报错
	    state.count += 1;
	  },
  }
});
// 方法二:分开

内容预览已结束

此内容需要会员权限。请先登录以查看完整内容。