@Environment 更改时 SwiftUI .onAppear 不会触发

问题描述 投票:0回答:1

我正在尝试将所有

@EnvironmentObject
转换为
@Environment
,但遇到了问题。
UserService
具有属性
user
,即
nil
。之后发生网络调用并且用户得到更新。这些更改会发布在视图中,但与以前不同,
.onAppear()
不会再次触发。我需要这个,因为一旦我有了
user
我需要调用 ViewModel 中需要用户的方法。

这以前工作得很好,但我猜幕后肯定发生了一些变化。有没有新的方法来处理这个问题?

@Observable class UserService {
    var user: User?
    
    var handle: AuthStateDidChangeListenerHandle?
    
    init() {
        print("UserService int()")
    }
    
    func listen() {
        handle = Auth.auth().addStateDidChangeListener({ (auth, user) in
            self.getCurrentUser(uid: user?.uid)
        })
    }
    
    func getCurrentUser(uid: String?) {
        guard let uid = uid else { return }
        Firestore.firestore().collection("users").document(uid).getDocument { documentSnapshot, error in
            do {
                self.user = try documentSnapshot?.data(as: User.self)
                print("getCurrentUser", self.user?.displayName)
            } catch {
                print("error")
                self.error = error.localizedDescription
            }
        }
    }
}

struct DiscoverView: View {
    @Environment(UserService.self) private var userService
    
    var body: some View {
        // OK gets updated when user is updated
        Text(userService.user?.displayName ?? "nil")
            .onAppear() {
                print("onAppear")
                if userService?.user {
                    //trigger something else 
                }
                // will trigger once and wont trigger when user is updated
            }
    }
}
ios swift xcode swiftui
1个回答
0
投票

在您的情况下仅调用一次

onAppear
实际上是正确的行为以及应该如何。

仅当 SwiftUI 视图的(结构)标识发生更改时,

onAppear
才会被多次调用。视图状态的更改不会导致多次调用
onAppear

要观察您的情况下

User
的变化,正确的方法是使用
onChange

Text(userService.user?.displayName ?? "nil")
    .onChange(of: userService.user) { oldUser, newUser in
        print("User changed: \(newUser?.displayName)")
    }
    .onAppear() {
        print("onAppear")
    }

如果

onAppear
在您的旧代码中被多次调用,这实际上可能表明您的视图层次结构和 SwiftUI 状态处理存在问题。 例如,使用条件视图修饰符可能会导致此问题。

© www.soinside.com 2019 - 2024. All rights reserved.