为什么我的SwiftUI列表在第一个HTTP请求后不更新为正确的用户对象?

huangapple go评论67阅读模式
英文:

Why is my SwiftUI List not updating with the correct User object after the first HTTP request?

问题

我有一个List,它迭代一个名为User的类实例数组,并显示一个带有每个元素属性的View。该视图显示具体User类实例的countReviews属性。类实例作为State变量传递给列表元素视图:

var users = [User]()

List {
    ForEach(users) { user in
        ReviewView(userVar: user)
    }
}

Review 结构体:

struct ReviewView: View {
    @State var userVar: User
    
    var body: some View {
        Text(String(userVar.countReviews))
            .task {
                await updateCount()
            }
    }

    func updateCount() async {
        // 从服务器返回一个 User 对象的 HTTP 请求
        // 一旦收到响应并解码了它:
        userVar = response.user
    }
}

User 类:

class User: Codable, Identifiable {
    let id: Int
    var countReviews: Int?
}

问题在于,当首次调用 updateCount() 函数时,userVar 被替换为新的 User 类实例。但当第二次调用时,userVar 对象继承自 users 变量的实例,不再更新。

英文:

I have a List that iterates an array of class instances named User and displays a View with properties of each element. The view has a text displaying the countReviews property of concrete User class instance. Class instances are passed to the list element view as a State variable:

var users = [User]()

List {
    ForEach(users) { user in
        ReviewView(userVar: user)
    }
}

Review struct:

struct ReviewView: View {
    @State var userVar: User
    
    var body: some View {
        Text(String(userVar.countReviews))
            .task {
                await updateCount()
            }
    }

    func updateCount() async {
        // HTTP request that returns a User object from server
        // Once response received and decoded with decoder:
        userVar = response.user
    }
}

User class:

class User: Codable, Identifiable {
    let id: Int
    var countReviews: Int?
}

The problem is, when the updateCount() function is called for the first time, the userVar is being replaced with the new User class instance. But when it's called for the second time, the userVar object inherits an instance from users variable and is not being updated anymore.

答案1

得分: 1

  1. 你可以将状态更改为 countReviews: Int? 并在任务中设置它。

  2. 将 User 更改为结构体。当结构体标记为 @State 时,它变为可变,您可以使用 mutating func 进行逻辑操作。对结构体属性的任何更改都会被检测为对状态的更改。

此外,如果您使用:

Text(userVar.countReviews, format: .number)

您将从用户更改其区域/语言时获益,自动重新格式化 UILabel 文本。

英文:
  1. You could change the state to countReviews: Int? and set it in the task.

  2. Change User to a struct. When a struct is @State it becomes mutable and you can use mutating func for logic. Any change to a property of a struct is detected as a change to the state.

Also if you use:

Text(userVar.countReviews, format: .number)

You'll benefit from auto reformatting of the UILabel text if the user changes their region/language.

huangapple
  • 本文由 发表于 2023年5月30日 05:39:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76360458.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定