# Viniendo de Jetpack Compose

> Mapeo @Composable→Component y el contador reactivo reescrito como campo + repaint().

Source: https://crossfly.dev/es/docs/migrate/from-jetpack-compose — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Viniendo de Jetpack Compose

En Compose (Kotlin declarativo) la UI **se recompone** cuando el estado observable cambia. En CrossFly tú
**montas una vez** y **mutas**. Lee primero [la filosofía](/docs/migrate/overview).

## Tabla de traducción
| Jetpack Compose | CrossFly |
|---|---|
| `@Composable fun` | método que monta **una vez** en `onShow()` |
| `remember { mutableStateOf(...) }` + recomposición | **campo** + `repaint()` (sin recomposición) |
| `Column` / `Row` / `Box` | `VerticalLayout` / `HorizontalLayout` / `RelativeLayout` |
| `Modifier.weight(1f)` | `add(LAY_FILL, c)` (`-1f`) |
| `Modifier.padding(...)` | `ingap` en el estilo |
| `LazyColumn` | `VirtualListView` |
| `Text` | `Label` |
| `Button` | `Button` |
| `Scaffold` / `TopAppBar` | `Window` (+ `TabBar`) |
| `NavController` / `NavHost` | pila de `Window` (`show()` / `hide()`) |
| `ViewModel` + `StateFlow` | ViewModel manual + callback (sin recolección de flujo) |
| `LaunchedEffect` / coroutines | `Thread` + `Component.onUI(...)` |
| `Color(0xFF...)` | `int 0xAARRGGBB` (`UIConstants` / `ColorUtils`) |

## Cómo era / cómo queda — el contador
```kotlin
// Compose: muda o state → recompõe sozinho
@Composable fun Contador() {
   var n by remember { mutableStateOf(0) }
   Column {
      Text("$n")
      Button(onClick = { n++ }) { Text("+") }
   }
}
```
```java
// CrossFly: guarda la referencia y actualiza a mano
public class Contador extends Window {
   private int n = 0;
   private Label display;
   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_AUTO, display = new Label("0"));
      Button mais = new Button("+");
      mais.onAction(c -> { n++; display.setText(String.valueOf(n)); });   // sin recomposición
      add(LAY_AUTO, mais);
   }
}
```

## El punto que más sorprende
`StateFlow`/`collectAsState` no tienen equivalente: CrossFly **no observa** tu estado. Donde
recolectarías un flujo, guarda el valor en un campo y llama a `repaint()` (o un `observe(Runnable)` manual en
tu ViewModel — ver [arquitectura de app](/docs/best-practices/arquitetura-de-app)).

## Véase también
- [Estado y flujo de datos](/docs/concepts/state-and-data-flow) · [Arquitectura de app](/docs/best-practices/arquitetura-de-app)
