Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A @State static property is being reinitiated without notice

I have a view which looks like this:

struct Login: View {

    @State static var errorMessage = ""

    init() {
        // ...
    }

    var body: some View {
        // ...
    }

}

I set errorMessage as static so I can set an error message from anywhere.

The problem is that even being static, it is always reinitiated each time the login view is showed, so the error message is always empty. I was thinking that maybe the presence of the init() method initiate it somehow, but I didn't figure how to fix this. What can I do?

like image 717
Cinn Avatar asked Oct 30 '25 22:10

Cinn


2 Answers

I set errorMessage as static so I can set an error message from anywhere.

This is a misunderstanding of @State. The point of @State variables is to manage internal state to a View. If something external is even looking at a @State variable, let alone trying to set it, something is wrong.

Instead, what you need is an @ObservableObject that is passed to the view (or is accessed as a shared instance). For example:

class ErrorManager: ObservableObject {
    @Published var errorMessage: String = "xyz"
}

This is the global thing that manages the error message. Anyone can call errorManager.errorMessage = "something" to set it. You can of course make this a shared instance if you wanted by adding a property:

 static let shared = ErrorManager()

With that, you then pass it to the View:

struct Login: View {
    @ObservedObject var errorManager: ErrorManager

    var body: some View {
        Text(errorManager.errorMessage)
    }
}

Alternately, you could use the shared instance if you wanted:

    @ObservedObject var errorManager = ErrorManager.shared

And that's it. Now change to the error automatically propagate. It's more likely that you want a LoginManager or something like that to handle the whole login process, and then observe that instead, but the process is the same.

like image 67
Rob Napier Avatar answered Nov 02 '25 13:11

Rob Napier


@State creates a stateful container that is associated with an instance of a view. Each instance of your view has it's own copy of that @State container.

In contrast, a static variable does not change across instances.

These two concepts are not compatible. You should not be using static with @State.

like image 29
Gil Birman Avatar answered Nov 02 '25 12:11

Gil Birman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!