求助:调用@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
相关产品推荐
相关产品推荐

