You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI子视图参数变更后未更新异步数据,如何每次参数变化时重新获取?

问题:子视图随参数变化重新获取异步数据

子视图拥有一个用于获取异步数据并展示的hostDate参数,父视图通过按钮触发该参数的变更,但当前代码中,子视图仅在首次加载时获取一次数据,参数变化后不会重新请求。示例代码如下:

struct Parent: View {
    
    @State var dayOffset: Int = 0
    
    var body: some View {
        VStack(spacing: 10) {
            Child(hostDate: Date().add(days: dayOffset))
            Button("Change day offset") {
                dayOffset += 1
            }
        }
    }
}


struct Child: View {
    
    let hostDate: Date
    
    @State var taskCount: Int = 0
    
    var body: some View {
        
        VStack(spacing: 10) {
            Text("host date is \(hostDate.description)")
            Text(" Task count is \(taskCount)")
        }
        .task {
            let summary = await DailySummary.of(hostDate)
            taskCount = summary.taskCount
        }
    }
}

请问如何实现每次参数变化时,子视图都重新获取异步数据?


解决方案

核心问题是默认的.task修饰符仅在视图首次出现时执行一次,不会响应hostDate的变化。只需给.task添加依赖标识,让它监听参数变化即可:

修改后的Child视图代码:

struct Child: View {
    let hostDate: Date
    
    @State var taskCount: Int = 0
    
    var body: some View {
        VStack(spacing: 10) {
            Text("host date is \(hostDate.description)")
            Text("Task count is \(taskCount)")
        }
        // 传入hostDate作为id,参数变化时重新执行异步任务
        .task(id: hostDate) {
            let summary = await DailySummary.of(hostDate)
            taskCount = summary.taskCount
        }
    }
}

原理说明

给.task添加id参数后,SwiftUI会自动监听该参数的变动:

  • 当hostDate更新时,会立即取消当前正在运行的异步任务(如果存在)
  • 启动新的异步任务获取对应日期的数据
  • 这种方式是官方推荐的简洁写法,无需手动管理任务生命周期,能避免重复请求或内存泄漏问题

内容的提问来源于stack exchange,提问作者runningJoey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:10:21