onevcat / OneV-s-Den-Comments

0 stars 0 forks source link

2021/12/tca-1/ #27

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

TCA - SwiftUI 的救星?(一) | OneV's Den

打算用几篇文章介绍一下 TCA (The Composable Architecture),这是一种看起来非常契合 SwiftUI 的架构方式。

https://onevcat.com/2021/12/tca-1/

remlostime commented 2 years ago

强力推荐tca的整个思考过程 - https://www.pointfree.co/collections/composable-architecture

remlostime commented 2 years ago

一些问题

  1. 在TEA中Model -> Update? 这个代表的是什么,为什么model的改变会回传给update? 类似于TCA里的side effect吗?还是其他的?

  2. Store 和 ViewStore的关系? 在TCA的作者视频里,其实还没有引入ViewStore的概念,作者是在Store上直接切片传给子view。这里的ViewStore是对Store的一个wrapper。我还是没搞明白为什么要有这个wrapper,ViewStore这个class具体做了什么? 我记得作者提到有这么一个类

    class A: ObservableObject {
    @Published var a: A
    @Published var b: B
    }

    即使 b没有改变,应用b的View也会被刷新,所以由于Apple本身的黑盒,所以要做些特殊处理,让只应用b的View不会被刷新。

  3. Composable 另外这里的composable arch我觉得如果对一个超大型的app,比如有100个子feature。把所有的action,state,reducer最后都聚合到root里是不现实的。列如

    
    RootAction {
    action1.... action100
    }

RootState { state1...state100 }

// Same for reducer



这里的聚合主要的目的是,当某些子feature共享某些state,root state类似于一个聚合器可以方便的通知他们。

那为什么不用类似于`subscription`的机制,让子feature去订阅需要的改变?同样实现了这个需求。
onevcat commented 2 years ago
  1. TEA 里应该是 Msg -> Model -> ( Model, Cmd Msg ),它等效于 Swift 的 (Msg, Model) -> (Model, Cmd<Msg>)。返回的新 Model 其实就和 Swift 的 inout state 是等价的。
  2. scope 负责划分 Store,把一个完整的 Store “切分”出来,让子 view 只需要关心它需要的部分,而不能随意访问到其他状态。ViewStore 负责提供对应 Store 的订阅,就 SwiftUI 的 WithViewStore 来说,它就是一个持有个 Observable store 的 View,可以相应 (切分后的这个) store 的状态变化。
  3. 事实上最后所有的 feature/action/reducer 就都是聚合到 root 中的。实际上要怎么划分,能形成一棵相对漂亮的树,就需要功力了。

那为什么不用类似于subscription的机制,让子feature去订阅需要的改变?同样实现了这个需求

对 Store 进行切分并使用 ViewStore 订阅,不就是这个意思么...

remlostime commented 2 years ago

对 Store 进行切分并使用 ViewStore 订阅,不就是这个意思么...

如果

  1. 一个项目不是一开始就用TCA,那就不太可能在Root就把所有state, action 切分给子feature。那新的TCA feature要订阅parent feature (not TCA),不是依然需要一种机制吗?
  2. 另外这里的 subscription 感觉应该更像 TEA里的 subscription,而且之前已经有讨论了在 TCA github issue。但似乎烂尾了
remlostime commented 2 years ago

ViewStore 负责提供对应 Store 的订阅,就 SwiftUI 的 WithViewStore 来说,它就是一个持有个 Observable store 的 View,可以相应 (切分后的这个) store 的状态变化。

我又看了下 TCA adaptation , ViewStore的主要功能

  1. Performance. 之前StoreObservableOjbect,任何state的改变都可能影响 parent view和 sub view。所以引入了ViewStore来避免性能的影响,是最主要的动机
  2. ViewStore inspired by ViewModel. 负责View方面的business logic。Store更加的通用,负责底层business logic。比如有iOSViewStoremacViewStore共享同一个Store
longlongago commented 2 years ago

喵神,感觉store 与viewstore的概念就是mvvm中m与vm的概念

suichou8 commented 2 years ago

这对项目质量的提升和保障可谓厥功至伟

厥功至伟这个成语用的真是恰如其分呀

shmilyQin commented 2 years ago

https://github.com/hollyoops/RecoilSwift 这个状态管理的库也不错

onevcat commented 2 years ago

@shmilyQin 感谢分享。我是第一次看到 recoil 的方式,有些概念似乎很有趣。

简单看了一下,感觉上主要是为了解决 TCA-like 里模板代码的问题。不过最近 TCA 新加了 Reducer Protocol,模板代码已经有很大改善了,Reducer 用 protocol 的方式来写,也基本没有太多额外负担了。

会持续关注,再次感谢。

DouKing commented 1 year ago

大佬,有点疑惑:将 SwiftUI 的 View 包裹在 WithViewStore 中,这个 view store 是不是就相当于 view controller 了?