Zenn
🐌

SwiftUIの@Stateに変化があると子Viewもinit(再描画)される

に公開
1

Viewの不要な再描画

@Stateに変化があると自身のbody内にある子Viewが、@Stateで保持されている値と関与していなくてもinit(再描画)されてしまいます。
そのためIncrementボタンをクリックするたびにDateViewのdateが更新されてしまいます。

import SwiftUI

struct ContentView1: View {
  @State var value: Int = 0

  var body: some View {
    VStack(spacing: 20) {
      Button("Increment \(value)") {
        value += 1
      }
      DateView()
    }
  }
}

struct DateView: View {
  var date: Date = .now

  var body: some View {
    Text("Date: \(date, format: .iso8601.time(includingFractionalSeconds: true))")
  }
}

#Preview {
  ContentView1()
}

対応方法

@Stateを持つViewを別にView(struct)に切り出すことでDateViewはinit(再描画)されなくなります。

struct ContentView2: View {
  var body: some View {
    VStack(spacing: 20) {
      CounterView()
      DateView()
    }
  }
}

struct CounterView: View {
  @State var value: Int = 0
  
  var body: some View {
    Button("Increment \(value)") {
      value += 1
    }
  }
}

#Preview {
  ContentView2()
}
1

Discussion

ログインするとコメントできます