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

如何正确传递返回对象的函数给Composable?解决调用上下文错误

解决Composable中调用ViewModel流函数的报错问题

你遇到的错误根源在于:collectAsStateWithLifecycle是带@Composable注解的函数,这类函数只能在@Composable上下文里调用。你传给FlightsScreen的lambda里用到了它,但你定义的getAirportDetails参数是普通的(String)->Airport类型(未标记@Composable),所以当FlightsScreen调用这个lambda时,相当于在非Composable上下文里调用了Composable函数,直接触发报错。

下面是两种正确的实现方式:


方式一:将参数函数标记为@Composable类型

直接修改FlightsScreen的参数定义,把getAirportDetails声明为带@Composable的函数类型,这样调用它时就处于合法的Composable上下文:

修改后的FlightsScreen定义:

@Composable
fun FlightsScreen(
    getAirportDetails: @Composable (String) -> Airport,
    // 其他必要参数...
) {
    // 内部调用逻辑保持不变
    val depart = getAirportDetails(favorite.departureCode)
    val arrival = getAirportDetails(favorite.destinationCode)

    FlightDetail(
        airport = depart,
        arrival = arrival,
        isFavorite = true,
        onFavoriteSelected = onFavoriteSelected
    )
}

父Composable调用代码无需修改:

FlightsScreen(
    getAirportDetails = { iataCode ->
        viewModel.getAirportByIata(iataCode)
            .collectAsStateWithLifecycle(initialValue = Airport(0,"","",0))
            .value
    },
    // 其他参数...
)

这种方式保留了你原本的组件拆分逻辑,让子组件负责触发数据获取,父组件提供具体的实现逻辑。


方式二:在父组件中提前收集状态,传递具体数据

如果不想让子组件依赖Composable类型的函数参数,可以在父组件中先收集好Airport的状态,再把具体的Airport实例传给子组件:

修改后的FlightsScreen定义:

@Composable
fun FlightsScreen(
    departAirport: Airport,
    arrivalAirport: Airport,
    isFavorite: Boolean,
    onFavoriteSelected: () -> Unit
) {
    FlightDetail(
        airport = departAirport,
        arrival = arrivalAirport,
        isFavorite = isFavorite,
        onFavoriteSelected = onFavoriteSelected
    )
}

父Composable调用代码:

// 先在父组件中完成状态收集
val departAirport = viewModel.getAirportByIata(favorite.departureCode)
    .collectAsStateWithLifecycle(initialValue = Airport(0,"","",0))
    .value
val arrivalAirport = viewModel.getAirportByIata(favorite.destinationCode)
    .collectAsStateWithLifecycle(initialValue = Airport(0,"","",0))
    .value

FlightsScreen(
    departAirport = departAirport,
    arrivalAirport = arrivalAirport,
    isFavorite = true,
    onFavoriteSelected = onFavoriteSelected
)

这种方式让子组件更纯粹,只负责展示数据,数据获取逻辑完全放在父组件或ViewModel中,适合逻辑简单的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:27:07