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

求助:调用@Composable函数报错「仅能在@Composable上下文调用」

解决「@Composable invocations can only happen from the context of a @Composable function」错误

问题根源

你在onTaskLongClicked这个普通lambda(类型为() -> Unit)里调用了AlertDialog这个@Composable函数,而Composable函数仅能在标注了@Composable的上下文(函数或lambda)中执行,普通lambda不具备这个上下文,因此触发报错。

修复方案

修改TaskItem的参数类型,为onTaskLongClicked添加@Composable注解,使其成为Composable类型的回调:

步骤1:更新TaskItem的函数定义

将原有的onTaskLongClicked: () -> Unit替换为onTaskLongClicked: @Composable () -> Unit:

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun TaskItem(
    task: Task,
    onItemCheckClicked: () -> Unit,
    onTaskClicked: () -> Unit,
    onTaskLongClicked: @Composable () -> Unit, // 新增@Composable注解
    modifier: Modifier = Modifier
) {
    // 原有Card、Row等代码保持不变
}

步骤2:保持调用代码不变

修改完TaskItem的参数类型后,原调用代码中onTaskLongClicked的lambda里的AlertDialog调用就不会再报错了:

task = task,
onItemCheckClicked = {
    tasksViewModel.onEvent(
        TasksScreenEvents.OnCheckTask(task.taskId)
    )
},
onTaskClicked = {
    navController.navigate(
        route = Screens.AddEditTaskScreen.passTaskId(
            taskId = task.taskId
        )
    )
},
onTaskLongClicked = {
    // 此处不再报错
    AlertDialog(
        onDismissRequest = { /*TODO*/ },
        confirmButton = { /*TODO*/ }
    )
}
)

原理说明

Compose的状态追踪和重组机制依赖@Composable标记的上下文,只有在这个上下文中,Compose才能识别并管理Composable函数的执行。将回调类型声明为@Composable () -> Unit,相当于告诉Compose这个lambda是在Composable上下文中执行的,允许内部调用其他Composable函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:42:23