LeetCode-OpenSource/ayanami

考虑支持类似mobx的computed特性吗

wangmingxu opened this issue · 7 comments

现在ayanami的类不支持使用getter,能否通过computed装饰器增加对getter的支持?
使用起来类似这样:
@computed get totalPrice() { const good = goodList[this.index] return good.number * good.price; }

In reactive way

totalPrice$ = this.state$.pipe(
  map((state) => {
    const good = state.goodList[state.index]
    return good.count * good.price
  })
)

@Effect()
buy(payload$: Observable<void>): Observable<EffectAction> {
  return payload$.pipe(
    exhaustMap(() => this.totalPrice$.pipe(
      exhaustMap((price) => http.post('/api/buy', { price }))
    ))
  )
}

如何在视图中获取到totalPrice呢?

每次 index 与 goodList 产生变动的时候在 reducer 里面 把 price 算出来放到 state 上

这样其实相当于在state上面新增一个price了,我更期望的是能根据state上面的goodList和index自动算出totalPrice,代码看起来会更加简洁

区别只是在于这坨计算 price 的代码放在 reducer 里面还是定义成 property 的 getter,代码一行也没少

Ayanami 虽然是 Class 但是不推荐在 this 上面保存状态,这样做容易让 SideEffect leak 到 Effect 之外的地方

我们希望写业务代码的时候 SideEffect(@effect),State Computing(@Reducer) 仅出现在特定的地方,而不是四处分散在 Module 的各个部分。这样会给读代码的人带来非常多的麻烦。

这也是为什么 useAyanmi 之后,只能读到 Module 上的 state 与 dispatcher 的原因

感谢解答,受教了

hinc commented

@Brooooooklyn Computed 相比 Reducer 一个是根据内部 state 变化进行「被动」computing,不涉及对 state 的 mutation,可以做到完全 reactive;另一个是根据外部或 Effect 中 Action 携带的 payload 进行 computing,需要「主动」dispatch Action。两者在 state computing 的场景不太一样,computedState 任何所依赖的 state 发生变化都需要主动 dispatch action 似乎浪费了部分 reactive 的优势,反而让相同的计算逻辑散落在 Module 各处。

另外赞同不应支持随意定义 property 的方式去表达 state,不知是否有更优雅的表达方式?