Composable Function: qué es, sintaxis de la función y reglas

Autor: IT Sectr Publicado: 2026-06-27 Tiempo de lectura: 8 min

Composable Function es una unidad fundamental de la interfaz de usuario en Jetpack Compose que define cómo debe verse y comportarse una parte de la pantalla. Cada una de estas funciones está marcada con la anotación @Composable y se ejecuta en un contexto especial que permite a Compose rastrear dependencias y reconstruir automáticamente la UI cuando los datos cambian. Según Google Android Developers, 2026, la construcción adecuada de las funciones Composable afecta directamente el rendimiento de la aplicación y la eficiencia de la recomposición.

Puntos clave

  • Composable Function — una función de Kotlin con la anotación @Composable que construye un árbol de UI
  • Los parámetros deben ser inmutables, los datos mutables van a través del state
  • La invocación solo es posible desde el contexto de otra función Composable
  • El orden de ejecución no está garantizado — cada función debe ser independiente
  • Modifier se recomienda pasarlo como parámetro para personalización

Qué es una Composable Function en Jetpack Compose

Una Composable Function es una función en el lenguaje Kotlin, marcada con la anotación @Composable, que describe una parte de la interfaz de usuario de manera declarativa. En lugar de crear y configurar objetos View a través de código Java o marcado XML, el desarrollador simplemente escribe cómo debería verse la UI para cada estado de los datos.

La principal diferencia entre una función Composable y el sistema tradicional de View de Android radica en el modelo de actualización. En el enfoque clásico, el desarrollador llamaba manualmente a findViewById, cambiaba el texto mediante setText y gestionaba la visibilidad con setVisibility. Composable Function te libera de esta rutina: cuando los datos cambian, el propio sistema determina qué funciones necesitan recomponerse y ejecuta solo esas.

El compilador de Kotlin, al procesar la anotación @Composable, genera código adicional que integra la función en el mecanismo de composición. Este código incluye lectura y escritura en slots — celdas de memoria especiales que almacenan el estado y los parámetros de cada función Composable en el árbol de UI actual. Gracias a esta integración, Compose sabe qué funciones dependen de qué datos.

Sintaxis de declaración de una función Composable

La sintaxis de una función Composable es extremadamente concisa: basta con añadir @Composable antes de la palabra clave fun. La función puede aceptar cualquier parámetro, incluir otras llamadas Composable en su cuerpo y usar construcciones de Kotlin — condiciones, bucles, expresiones when — para el renderizado condicional de la UI.

kotlin
@Composable
fun ProductItem(
    product: Product,
    modifier: Modifier = Modifier,
    onAddToCart: () -> Unit
) {
    Card(modifier = modifier.padding(8.dp)) {
        Row(modifier = Modifier.fillMaxWidth().padding(12.dp),
            verticalAlignment = Alignment.CenterVertically) {
            Column(modifier = Modifier.weight(1f)) {
                Text(text = product.name, style = MaterialTheme.typography.titleMedium)
                Text(text = "${product.price}", color = MaterialTheme.colorScheme.primary)
            }
            Button(onClick = onAddToCart) {
                Text("Añadir al carrito")
            }
        }
    }
}

En este ejemplo, la función Composable ProductItem acepta un objeto Product, un modificador y un callback. Los tres parámetros son inmutables, lo que garantiza un comportamiento predecible durante la recomposición. El modificador se pasa como parámetro con un valor por defecto — esta es una práctica estándar que permite a la parte llamante personalizar los paddings y tamaños.

Componentes y modificadores en funciones Composable

Dentro de una función Composable se utilizan componentes integrados de Material Design (Text, Button, Card, TextField) o primitivas fundamentales (Canvas, Layout). Cada componente acepta parámetros para configurar la apariencia y el comportamiento, así como uno o más modificadores a través del parámetro modifier.

Los modificadores son una cadena de funciones que cambian el tamaño, la posición, el manejo de eventos y la apariencia de un componente. El orden de los modificadores en la cadena importa: clickable.semantics funciona de manera diferente a semantics.clickable, y padding.background pinta tanto el área como el fondo incluyendo el padding, lo cual es crítico al diseñar.

Dentro de una función Composable, puedes usar condiciones if y when para el renderizado condicional de partes de la UI, así como bucles for para listas dinámicas. Todas estas construcciones funcionan de manera natural porque Kotlin es un lenguaje de programación completo. Sin embargo, es importante recordar: si una condición o bucle contiene llamadas a funciones Composable, también participan en la recomposición.

kotlin
@Composable
fun ProductList(
    products: List<Product>,
    modifier: Modifier = Modifier
) {
    LazyColumn(modifier = modifier) {
        items(products, key = { it.id }) { product ->
            ProductItem(
                product = product,
                onAddToCart = { /* add to cart */ }
            )
        }
    }
}

Ejemplos de funciones Composable para pantallas reales

Consideremos un ejemplo de una pantalla de búsqueda de productos usando varias funciones Composable. Aquí se muestran patrones típicos: un campo de entrada con estado, filtrado de lista, manejo de resultados vacíos y carga.

kotlin
data class Product(
    val id: String,
    val name: String,
    val price: Double,
    val category: String
)

@Composable
fun SearchScreen() {
    var query by remember { mutableStateOf("") }
    val products = remember(query) { getFilteredProducts(query) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        OutlinedTextField(
            value = query,
            onValueChange = { query = it },
            label = { Text("Buscar productos") },
            modifier = Modifier.fillMaxWidth()
        )

        Spacer(modifier = Modifier.height(16.dp))

        when (products) {
            is Loading -> CircularProgressIndicator()
            is Empty -> Text("No se encontraron resultados")
            is Result -> LazyColumn {
                items(products.items, key = { it.id }) { product ->
                    ProductItem(product = product, onAddToCart = {})
                }
            }
        }
    }
}

Este ejemplo demuestra varios modismos a la vez: remember para preservar el estado de la consulta de búsqueda, remember(query) para filtrar con una clave, when para tres estados de UI y LazyColumn para el renderizado eficiente de listas. Cada uno de estos modismos es el resultado de la experiencia práctica en el desarrollo de aplicaciones Compose.

Parámetros y Slot API

Las funciones Composable aceptan parámetros igual que las funciones Kotlin normales, pero con una diferencia importante: un parámetro puede ser otra función Composable pasada a través de una lambda con la anotación @Composable. Este mecanismo se llama Slot API y es el patrón principal para crear contenedores reutilizables.

El Slot API resuelve el problema que en el sistema tradicional de View se resolvía mediante ViewGroup y la adición programática de Views hijas. En lugar de métodos addView, Compose utiliza lambdas content — el último parámetro con el tipo @Composable () -> Unit. La parte llamante pasa cualquier UI dentro de esta lambda, y el contenedor solo define su disposición.

Los parámetros de las funciones Composable pueden tener valores por defecto, lo que simplifica su uso en diferentes contextos. Se recomienda hacer obligatorios solo aquellos parámetros sin los cuales la función no puede realizar su tarea, y proporcionar valores por defecto razonables para el resto.

ParámetroTipoEjemplo
ObligatorioCualquier tiponame: String
OpcionalCon valor por defectomodifier: Modifier = Modifier
Content@Composable () -> Unitcontent: @Composable () -> Unit
CallbackLambda sin @ComposableonClick: () -> Unit

Modismos de funciones Composable en Kotlin

En la comunidad de Compose han surgido varios modismos establecidos que hacen que las funciones Composable sean más legibles y predecibles. El primero es State Hoisting: el estado se eleva a un nivel superior, y la función Composable lo recibe a través de parámetros. Esto hace que la función sea pura y reutilizable en diferentes contextos.

El segundo modismo son los parámetros Event-driven. En lugar de pasar una ViewModel o useCase a una función Composable, solo se pasan callbacks específicos: onSave, onDelete, onNavigateToDetail. Esto reduce el acoplamiento y simplifica las pruebas — una prueba para ProductItem no necesita una ViewModel, solo un stub de lambda.

El tercer modismo es CompositionLocal para pasar datos compartidos a través del árbol de composición. El tema, la densidad de pantalla, la ruta actual — todo esto se pasa a través de CompositionLocal, evitando cadenas de parámetros a través de docenas de funciones Composable. Sin embargo, no se debe abusar de CompositionLocal: los parámetros explícitos siempre son preferibles a las dependencias implícitas.

kotlin
// State Hoisting: estado elevado a la función padre
@Composable
fun CounterDisplay(
    count: Int,
    onIncrement: () -> Unit
) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Contador: $count", style = MaterialTheme.typography.headlineLarge)
        Button(onClick = onIncrement) {
            Text("+1")
        }
    }
}

// Uso con State Hoisting
@Composable
fun CounterScreen() {
    var count by remember { mutableStateOf(0) }
    CounterDisplay(
        count = count,
        onIncrement = { count++ }
    )
}

Preguntas frecuentes

¿Se puede usar return en una función Composable?

Sí, return está permitido, pero con precaución. Compose optimiza la recomposición a nivel de funciones individuales, y un return temprano puede romper esta optimización. Es mejor usar operadores condicionales if o when dentro del cuerpo de la función.

¿En qué se diferencia Unit-return de void en Java?

En Kotlin, Unit es un objeto singleton, no un tipo vacío. Las funciones Composable devuelven Unit, lo que técnicamente significa que devuelven el propio objeto Unit. Sin embargo, en la práctica esto no importa — el valor de retorno es ignorado por el sistema de composición.

¿Se puede pasar mutableListOf a una función Composable?

Pasar colecciones mutables es posible, pero es una mala práctica. Si la colección cambia, Compose no lo sabrá porque la referencia al objeto sigue siendo la misma. Usa listas inmutables o mutableStateListOf para cambios rastreados.

¿Cómo depurar una función Composable?

Para depurar, usa Android Studio con Layout Inspector, que muestra el árbol actual de funciones Composable, los valores de los parámetros y las razones de la recomposición. El depurador normal de Kotlin también funciona — los puntos de interrupción dentro de las funciones Composable se activan correctamente en cada recomposición.

¿Es obligatorio especificar el tipo de retorno de una función Composable?

Una función Composable siempre devuelve Unit, por lo que no se especifica el tipo de retorno. Intentar devolver otro tipo causará un error de compilación porque la anotación @Composable es incompatible con tipos de retorno que no sean Unit.

Resumen

  • Composable Function — un bloque de construcción declarativo de UI marcado con @Composable
  • Los parámetros deben ser inmutables para una recomposición predecible
  • Los modificadores y Slot API proporcionan flexibilidad y reutilización sin herencia
  • State Hoisting — elevar el estado hacia arriba para limpieza y capacidad de prueba
  • Callbacks Event-driven reducen el acoplamiento con ViewModel y la lógica de negocio
  • CompositionLocal se usa para datos compartidos, pero los parámetros explícitos son preferibles
  • Los modismos de Compose hacen que el código sea predecible, comprobable y eficiente

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también