Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

State and data flow

This is where CrossFly most surprises those coming from Flutter, Compose, SwiftUI, or React. Two deliberate absences:

  • There is no automatic reactive binding. No setState, observables, @State, or recomposition. Changing the model does not update the UI on its own.
  • There is no dependency injection container. No Dagger/Guice/Spring. You build and pass your dependencies by hand (typically through the screen’s constructor).

The model: imperative + explicit invalidation

You read/write the model, update the component directly, and the framework repaints:

model.nome = "Ana";
label.setText(model.nome);   // most setters already invalidate the layout and call repaint()

Most component setters already fire repaint()/invalidate the layout for you. The single rule to remember:

Changed state the framework doesn’t know about (a counter of yours, a computation, a field drawn in onPaint)? You call repaint(). (See The paint thread.)

The classic counterexample

this.progresso = 0.7f;   // I changed a field that only my onPaint reads…
// …and the screen doesn't change. Missing:
Component.repaint();      // ✔ now the next frame reflects the new value

“I changed the state and the screen didn’t update” is, almost always, a missing repaint().

Why this choice

  • Predictability: the flow is linear and visible — data → setter → repaint → frame. There is no magic recomposition nor hidden reactive cycle to debug.
  • Zero magic, low cost: no reactive dependency graph, no DI framework to configure.
  • The price is explicitness: managing state is the application’s responsibility, not the framework’s.

The communication mechanisms the framework offers

  • Callbacks / actions — onAction(...), callbacks passed through the constructor (see Returning results).
  • Parent/child hierarchy — navigate the component tree.
  • property(k, v) — the per-component “data bag” (see Everything is a Component).
  • Global state — static fields/shared services when it makes sense.

Since the framework only provides the building blocks, the organization pattern (a ViewModel/controller per screen + repository for data) is an application convention — documented in best-practices. The framework does not impose an architecture; it offers components and the setter→repaint() pair.

reads

setText / setItems

repaint

onAction

model / repository

ViewModel (yours)

Component

next frame

See also

Was this page helpful?