Content Map
Organized content by level and language.
Beginner — Start here
Intermediate — Level up
Advanced — Deep dives
Español — Contenido en español
---
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:
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
useEffectlogic 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
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
useEffectcon 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