JavaScriptを有効にしてください

ReduxとSwiftUIについて

 ·  ☕ 3 min read

Redux

  • 状態は複数のView, Controllerが相互に依存するので管理が難しい

  • そこで,相互にイベントを発火させるのをやめて,単一方向にのみ状態が流れるように

    • ユーザ操作で変数が変更→変更を検知したらレンダリング
    • flux
  • さらに,変数変更とレンダリングの間に更新ロジックを挟むのがRedux

  • Reduxはグローバルな状態を管理するのが目的.コンポーネント内部で完結する変数はStoreで管理しないほうがbetter

    • 更新するたびにレンダリングが走るのでパフォ落ちる
  • Q. これはグローバル変数と広義的には同義では?

    • A. ほぼ合ってる(要出典)
    • そもそもグローバル変数はなぜ嫌われるか
      • 主な理由は「誰でもいつでもアクセスできるから」
      • あるロジックの動作中に別のロジックが変数を変えてしまうことで一貫性が崩れる.
    • ならば,関数を変数ドリブンにして,変数が変わったら常に"イベントが発火→同期"されれば良い
    • 「関数の発火点を変数の変更イベントにする⇔単一フロー」が肝
    • このフローをフレームワークに落とし込んだのがRedux




SwiftUIとpure UIKitにおける状態管理の違い

  • SwiftUIはSingle Source of Truthを標榜

    • Single Source of Truth : 簡単に言えば変数のコピーを作らない.変数は同期されるべきという思想.
      • 関数を変数ドリブンにして,変数が変わったら常に"イベントが発火→同期"されれば良い
    • SwiftUIでは,Redux同様,この「同期処理」が全て内部で行われる.
    • ここがUIKitとの違いであり,SwiftUIでは同期処理を自前で書いてはならない
  • 自前での同期処理って具体的には何?

    • didSetによるview変更
    • 自前で書いてしまうと,書き忘れが生じたりコーディング量が増大するため,好ましくない.
  • pureなUIKitの例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class SampleViewController: UIViewController {
    var labelState: Bool = false {
        didSet { // 自前で書いた同期処理
            label.text = "\(labelState)"
        }
    }
    @IBOutlet weak var label: UILabel!
    @IBAction func switchToggle(_ sender: UISwitch) {
        self.labelState = sender.isOn
    }
}
  • SwiftUIの例
1
2
3
4
5
6
7
8
9
struct SampleView: View {
    @State private var labelState = false
    var body: some View {
        VStack {
            Toggle(isOn: $labelState, label: {})
            Text("\(labelState)").padding()
        }
    }
}
  • View間の状態管理は@Bindingを付けることで実現される.
  • SwiftUIの状態管理は小さいReduxのような感じ
共有

YuWd (Yuiga Wada)
著者
YuWd (Yuiga Wada)
機械学習・競プロ・iOS・Web