Hosted onhyper.mediavia theHypermedia Protocol

Content Map

Organized content by level and language.

---

English

<!-- embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/you-are-writing-ui-state-wrong?v=bafy2bzacecxbssfu6tsgckkty6krdldbq232rib3mvbbxhfhi745pqg4m7zsg&l; title: You are Writing UI State Wrong; version: bafy2bzacecxbssfu6tsgckkty6krdldbq232rib3mvbbxhfhi745pqg4m7zsg --> Tienes la version en español Aqui! Why state machines make UI logic simpler, safer, and way more maintainable.

🤯 The UI Logic Spiral

Let's be honest: your React component's state logic probably started simple.

A couple of booleans. Maybe a useEffect. Just enough to get things working.

But then things changed:

  • You added a loading state.

  • Then an error state.

  • Then a retry flow.

  • Then an edge case where loading _and_ error coexist.

Now you're juggling isLoading, hasError, isSubmitting, showModal, and a nest of if/else blocks — and you're still not sure you've covered all the cases.

Sound familiar?

🧠 UIs Aren't Just State — They're Behavior

We often treat UI state as a flat structure of booleans or enums.

But in reality, your UI is a process. A sequence. A user clicks a button, something happens, and the UI responds.

That's not just _state_. That's _state over time_ — and that's exactly what state machines are made for.

✅ The Solution: Model Behavior, Not Just State

What if, instead of wiring together a dozen flags, you modeled your UI logic as a state machine?

With a state machine, you:

  • Define all possible states up front

  • Describe _only_ valid transitions

  • Eliminate contradictory or impossible states

  • Get a visual map of your logic — for free

Let's look at a simple example.

🧪 Example: Toggle with XState

    import { createMachine } from 'xstate';

const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' },
    },
    active: {
      on: { TOGGLE: 'inactive' },
    },
  },
});

That's it.

One machine. Two states. One event. No booleans. No conditionals. No useState.

Simple, expressive, and type-safe.

🔍 Visualizing It

Here's what that machine _actually_ looks like:

State machine visualizer from stately.aiState machine visualizer from stately.ai

Tools like Stately.ai let you see your machines as flow diagrams — so you and your team instantly understand what's going on.

🛠️ Why This Matters

This isn't just for toggles. You can use state machines to:

  • Simplify multi-step forms and wizards

  • Model modals, dropdowns, or onboarding flows

  • Eliminate inconsistent UI states

  • Replace messy useEffect logic with declarative transitions

And when you pair XState + React + TypeScript, you unlock type-safe, testable UI logic that scales.

⏭️ Coming Up Next: States, Events, and Transitions

In the next issue, we'll break down the three building blocks of any state machine — and how to spot them in your own components.

You'll learn how to go from messy state to modeled behavior in minutes.

💡 Try This

Pick a small UI interaction in your app — a toggle, modal, or dropdown — and try modeling it as a state machine.

Just one.

Then ask yourself: _was this easier to reason about?_

Hit reply and let me know how it went — or tag me on Twitter/X. I'll feature a few community examples in future issues.

Thanks for reading, Horacio <!-- /embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/you-are-writing-ui-state-wrong?v=bafy2bzacecxbssfu6tsgckkty6krdldbq232rib3mvbbxhfhi745pqg4m7zsg&l -->

<!-- embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/states-events-and-transitions-demystified?v=bafy2bzaceasflmgw6yafc3mygkufwzsrzcjoh5vbpczy532qvitkfsli3icns&l; title: States, Events, and Transitions, Demystified; version: bafy2bzaceasflmgw6yafc3mygkufwzsrzcjoh5vbpczy532qvitkfsli3icns --> State machines can sound intimidating at first — all those diagrams and boxes and arrows. But at the heart of it, they're built on three incredibly simple ideas: states, events, and transitions. If you've ever handled a button click or shown a loading spinner, you've already worked with them. This week, we're going to demystify how these pieces fit together and why they can make your UI logic feel like it finally _makes sense_.

✨ Intro: The Foundation of Every State Machine

In the last issue, we looked at why state machines are a better way to model UI logic. This week, we're breaking down the three concepts that power every state machine:

States – the different modes your UI can be in

Events – the things that happen to trigger change

Transitions – how you move from one state to another

Once you understand these, even the most complex flows start to feel… obvious.

🧠 What Is a State?

A state is just a label for a condition your UI is in.

🔁 Example: A toggle switch has two states: active and inactive. A form might have: idle, validating, submitting, success, error.

You define them up front — and your component can only be in one of them at a time.

⚡ What Is an Event?

An event is something that happens — usually triggered by the user or the system.

👇 Examples:

A click → TOGGLE

A form submission → SUBMIT

An API call fails → FAILURE

Events don't do anything on their own — they ask the machine to change.

🔄 What Is a Transition?

A transition is how the machine changes from one state to another in response to an event.

Think of it as: "When I'm in [this state] and [this event] happens, move to [that state]."

In XState, it looks like this:

      createMachine({
  initial: 'idle',
  states: {
    idle: {
      on: { SUBMIT: 'submitting' }
    },
    submitting: {
      on: {
        SUCCESS: 'success',
        FAILURE: 'error'
      }
    },
    success: {},
    error: {}
  }
});

🧪 Why This Structure Is Powerful

Because you define states and transitions explicitly, you avoid:

Ambiguous conditions

Invalid combinations (e.g. isLoading && isError)

"Where am I in the flow?" type bugs

The machine won't allow transitions that aren't defined. That's safety by design.

Visualize It

Here's that form state machine as a diagram:

Diagrams like this aren't just pretty — they're living documentation of how your app behaves.

🧠 Pro Tip: Events Are the API of Your Component

Instead of exposing a bunch of props or handlers, you can think of your UI machine as exposing one clean interface:

    send({ type: 'SUBMIT' });

That's it. Consumers of your component don't care about your internal logic — they just send events and get predictable behavior.

Coming Up Next: Modeling UI with XState

In the next issue, we'll get hands-on: ✅ Setting up XState in a React project ✅ Using useMachine ✅ Connecting state to your UI

We'll build a real machine and hook it into a real component.

💡 Try This

Pick a small UI in your app (a toggle, button, form, etc) and answer:

  • What are the possible states?

  • What events can happen?

  • How do you transition from one to another?

Try modeling it on paper — or in Stately.ai

Reply to this with your flow — I'd love to feature a few in future issues!

Until next time, Horacio <!-- /embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/states-events-and-transitions-demystified?v=bafy2bzaceasflmgw6yafc3mygkufwzsrzcjoh5vbpczy532qvitkfsli3icns&l -->

Spanish

<!-- embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/you-are-writing-ui-state-wrong/estas-gestionando-el-estado-de-tus-interfaces-mal?v=bafy2bzacedeehy4mmf4hniuuxqoww54eacrhpypjtzu5qotzkgrq2bm6lfmqm&l; title: Estas gestionando el estado de tus Interfaces mal; version: bafy2bzacedeehy4mmf4hniuuxqoww54eacrhpypjtzu5qotzkgrq2bm6lfmqm --> Por qué las máquinas de estados hacen que la lógica de UI sea más simple, segura y mantenible.

🤯 El espiral de la lógica en la UI

Seamos sinceros: probablemente la lógica de estado en tu componente de React empezó siendo simple.

Un par de booleanos. Tal vez un useEffect. Lo justo para que funcione.

Pero luego las cosas se complicaron:

  • Agregaste un estado de carga.

  • Después, un estado de error.

  • Luego, un flujo de reintento.

  • Y finalmente, un caso raro donde hay carga _y_ error al mismo tiempo.

Ahora estás manejando isLoading, hasError, isSubmitting, showModal, y una maraña de if/else, y aún así no estás seguro si cubriste todos los casos.

¿Te suena familiar?

🧠 Las UIs no son solo estados — son comportamientos

A menudo tratamos el estado de UI como una estructura plana de booleanos o enums.

Pero en realidad, tu UI es un proceso. Una secuencia. Un usuario hace clic, algo sucede, y la UI responde.

Eso no es solo _estado_. Es _estado a través del tiempo_ — y eso es exactamente lo que una máquina de estados modela.

✅ La solución: modela comportamientos, no solo estados

¿Qué pasaría si, en vez de conectar un montón de banderas y condiciones, modelaras la lógica de tu UI como una máquina de estados?

Con una máquina de estados, puedes:

  • Definir todos los estados posibles desde el principio

  • Describir _solo_ las transiciones válidas

  • Eliminar estados imposibles o contradictorios

  • Tener un mapa visual de tu lógica — gratis

Veamos un ejemplo simple.

🧪 Ejemplo: Toggle con XState

  import { createMachine } from 'xstate';

const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' },
    },
    active: {
      on: { TOGGLE: 'inactive' },
    },
  },
});

Eso es todo.

Una máquina. Dos estados. Un evento. Sin booleanos. Sin condicionales. Sin useState.

Simple, expresivo y con tipado fuerte.

🔍 Visualízalo

Diagrama de La Maquina de estado en Stately.aiDiagrama de La Maquina de estado en Stately.ai

Así es como _realmente_ luce esa máquina: Button

Herramientas como Stately.ai te permiten ver tus máquinas como diagramas de flujo — para que tú y tu equipo entiendan instantáneamente lo que está pasando.

🛠️ ¿Por qué importa esto?

Esto no es solo para toggles. Puedes usar máquinas de estados para:

  • Simplificar formularios multistep y asistentes

  • Modelar modales, menús desplegables o flujos de onboarding

  • Eliminar estados inconsistentes en la UI

  • Reemplazar lógica useEffect con transiciones declarativas

Y cuando combinas XState + React + TypeScript, desbloqueas una arquitectura de UI segura, testeable y escalable.

⏭️ Próximo tema: Estados, Eventos y Transiciones

En el siguiente número, vamos a desglosar los tres bloques fundamentales de cualquier máquina de estados — y cómo identificarlos en tus propios componentes.

Vas a aprender cómo pasar de un estado caótico a un comportamiento modelado en minutos.

💡 Intenta esto

Elige una interacción pequeña en tu UI — un toggle, modal o dropdown — e intenta modelarla como una máquina de estados.

Solo una.

Y luego pregúntate: _¿fue más fácil razonar sobre esto?_

Responde este correo y cuéntame cómo te fue — o etiquéteme en Twitter/X. Voy a destacar algunos ejemplos interesantes en futuros envíos. Gracias por leer, Horacio <!-- /embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/you-are-writing-ui-state-wrong/estas-gestionando-el-estado-de-tus-interfaces-mal?v=bafy2bzacedeehy4mmf4hniuuxqoww54eacrhpypjtzu5qotzkgrq2bm6lfmqm&l -->

<!-- embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/estados-eventos-y-transiciones-desmitificados; title: Estados, eventos y transiciones, desmitificados --> Las máquinas de estado pueden sonar intimidantes al principio: tantos diagramas, cajas y flechas. Pero, en esencia, están construidas sobre tres ideas increíblemente simples: estados, eventos y transiciones. Si alguna vez has manejado el clic de un botón o mostrado un indicador de carga, ya has trabajado con ellas. Esta semana vamos a desmitificar cómo encajan estas piezas y por qué pueden hacer que la lógica de tu UI por fin tenga sentido.

✨ Introducción: La base de toda máquina de estado

En la edición anterior, vimos por qué las máquinas de estado son una mejor forma de modelar la lógica de la UI. Esta semana vamos a desglosar los tres conceptos que impulsan toda máquina de estado:

Estados – los diferentes modos en los que puede estar tu UI

Eventos – las cosas que ocurren y desencadenan cambios

Transiciones – cómo pasas de un estado a otro

Una vez que entiendes esto, incluso los flujos más complejos empiezan a parecer… obvios.

🧠 ¿Qué es un estado?

Un estado es simplemente una etiqueta para una condición en la que se encuentra tu UI.

🔁 Ejemplo: Un interruptor tiene dos estados: activo e inactivo. Un formulario podría tener: inactivo, validando, enviando, éxito, error.

Los defines de antemano, y tu componente solo puede estar en uno de ellos a la vez.

⚡ ¿Qué es un evento?

Un evento es algo que sucede, normalmente desencadenado por el usuario o por el sistema.

👇 Ejemplos:

Un clic → TOGGLE

El envío de un formulario → SUBMIT

Una llamada a la API falla → FAILURE

Los eventos no hacen nada por sí solos: le piden a la máquina que cambie.

🔄 ¿Qué es una transición?

Una transición es la forma en que la máquina cambia de un estado a otro en respuesta a un evento.

Piensa en ello así: "Cuando estoy en [este estado] y ocurre [este evento], paso a [aquel estado]".

En XState, se ve así:

  createMachine({
  initial: 'idle',
  states: {
    idle: {
      on: { SUBMIT: 'submitting' }
    },
    submitting: {
      on: {
        SUCCESS: 'success',
        FAILURE: 'error'
      }
    },
    success: {},
    error: {}
  }
});

🧪 Por qué esta estructura es poderosa

Porque defines explícitamente los estados y las transiciones, evitas:

Condiciones ambiguas

Combinaciones inválidas (por ejemplo, isLoading && isError)

Errores del tipo "¿en qué parte del flujo estoy?"

La máquina no permitirá transiciones que no estén definidas. Eso es seguridad por diseño.

Visualízalo

Aquí está ese formulario como un diagrama de máquina de estados: Button Este tipo de diagramas no solo se ven bien: son documentación viva de cómo se comporta tu aplicación.

🧠 Consejo profesional: Los eventos son la API de tu componente

En lugar de exponer un montón de props o handlers, puedes pensar en la máquina de tu UI como una interfaz limpia que expone una sola cosa:

  send({ type: 'SUBMIT' });

Eso es todo. A quienes consumen tu componente no les importa tu lógica interna: solo envían eventos y obtienen un comportamiento predecible.

Próximamente: Modelando UI con XState

En la próxima edición, pasaremos a la práctica:

  • ✅ Configurar XState en un proyecto de React

  • ✅ Usar useMachine

  • ✅ Conectar el estado a tu UI

Vamos a construir una máquina real y conectarla a un componente real.

💡 Prueba esto

Elige una UI pequeña en tu aplicación (un interruptor, botón, formulario, etc.) y responde:

  • ¿Cuáles son los estados posibles?

  • ¿Qué eventos pueden ocurrir?

  • ¿Cómo pasas de uno a otro?

Intenta modelarlo en papel o en Stately.ai.

Responde con tu flujo; me encantaría destacar algunos en futuras ediciones. Hasta la próxima, Horacio <!-- /embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/estados-eventos-y-transiciones-desmitificados -->

<!-- embed: hm://z6MkhBiheioCs7btwVLUcnSCcFPdhTGGHSHpR4SHTyAobUUp/content/why-state-machines-are-a-game-changer-for-ui-development; title: Why State Machines Are a Game-Changer for UI Development -->

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime