I am not sure if I use it properly, but the case is the following:
I have a View:
struct TimerView: View {
@State private var numberOfVideos: Int
@State private var time = ""
private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
init(numberOfVideos: Int) {
_numberOfVideos = State(initialValue: numberOfVideos)
}
var body: some View {
Text(time)
.onReceive(timer) { _ in
// it is called every second
time = "00:00"
}
ReportView(numberOfVideos: $numberOfVideos)
}
}
struct ReportView: View {
@Binding private var numberOfVideos: Int
init(numberOfVideos: Binding<Int>) {
// ❌ this is called every second, I don't want it.
self._numberOfVideos = numberOfVideos
}
var body: some View {
Text(String(numberOfVideos))
}
}
Usage:
TimerView(numberOfVideos: 5)
Instantiating ReportView
every second this is not what I need. How can I fix this?
2
Answers
The problem is that you are storing
numberOfVideos
asBinding
onReportView
.You should only use
Binding
to inject mutable state into subviews, which you want to redraw whenever that mutable state changes either from inside or outside the view.Since you are never mutating
numberOfVideos
from insideReportView
, you should store it as an immutable property. IfTimerView
would updatenumberOfVideos
, that would redraw the wholeTimerView
and hence create a newReportView
with the updated number as well.This ensures that
ReportView
isn’t recreated every timetime
is updated onTimerView
.Jut move timer logic in separate view like this: