Construye un flujo tipo Wizard en React con estados locales, tipado seguro en TypeScript y una configuración clara de máquina de estados. Aquí se define desde cero el componente StateMachineWizard, se importa la configuración StateMachineConfig, se manejan los pasos con un current step y se renderiza cada vista con getStepView. Además, se valida si se puede avanzar con canAdvance antes de mostrar el botón next y llegar a confirmation.
¿Cómo se estructura el StateMachineWizard en React?
El componente se crea desde cero y reemplaza la App inicial. Se definen dos estados locales: uno para los datos del formulario y otro para el paso actual. La configuración StateMachineConfig aporta el initialStep, los steps y las views indexadas por una key.
¿Qué estados locales gestionan el wizard?
- Estado de datos: name y age con useState; age inicia en 0.
- Estado de navegación: current step con el initialStep de la StateMachineConfig.
- Separación de responsabilidades: datos internos vs. paso actual.
¿Cómo se integra la StateMachineConfig inicial?
- Se importa StateMachineConfig y se usa su initialStep para iniciar el flujo.
- La configuración contiene views indexadas por la key del paso.
- Las keys representan “paso uno”, “paso dos” y “confirmation”.
¿Cómo se renderiza la vista del paso con getStepView?
- Se define una función genérica getStepView con tipos T y B que extiende de string.
- Retorna un ComponentType de React que recibe props: state y setState.
- Con la key del paso (stepName) se toma la vista: conf.views[stepName].
import React, { useState } from 'react';
import { StateMachineConfig } from './StateMachineConfig';
function getStepView<T, B extends string>(
conf: StateMachineConfig<T, B>,
stepName: B
): React.ComponentType<{
state: T;
setState: React.Dispatch<React.SetStateAction<T>>;
}> {
return conf.views[stepName];
}
export default function StateMachineWizard() {
const [wizardState, setWizardState] = useState({ name: '', age: 0 });
const [currentStep, setCurrentStep] = useState(StateMachineConfig.initialStep);
const StepComponent = getStepView(StateMachineConfig, currentStep);
return (
<section>
<h1>State Machine Wizard ✨🧭</h1>
<StepComponent state={wizardState} setState={setWizardState} />
{/* botón next se controla más abajo */}
</section>
);
}
¿Cómo se avanza entre pasos con validación canAdvance?
Se implementa una función handleNext que consulta en la configuración si se puede avanzar desde el paso actual. Si canAdvance es verdadero, se cambia el current step; si no, se muestra un alert con un mensaje claro.
¿Qué hace handleNext con la configuración?
- Lee StateMachineConfig.steps[currentStep].canAdvance(wizardState).
- Si devuelve true y estás en “paso uno”, cambia a “paso dos”.
- Si estás en “paso dos”, cambia a “confirmation”.
- Si no puede avanzar, muestra: "You can't move forward yet".
const handleNext = () => {
const canAdvance = StateMachineConfig.steps[currentStep].canAdvance(wizardState);
if (canAdvance) {
if (currentStep === 'stepOne') {
setCurrentStep('stepTwo');
} else if (currentStep === 'stepTwo') {
setCurrentStep('confirmation');
}
} else {
alert("You can't move forward yet");
}
};
¿Cuándo se muestra el botón next en las vistas?
- Se renderiza solo en “paso uno” y “paso dos”.
- En “confirmation” no se muestra el botón.
- Se usa onClick para disparar handleNext.
return (
<section>
<h1>State Machine Wizard ✨🧭</h1>
<StepComponent state={wizardState} setState={setWizardState} />
{currentStep !== 'confirmation' && (
<button onClick={handleNext}>next</button>
)}
</section>
);
¿Qué prácticas y keywords debes recordar?
Adoptar una máquina de estados facilita el control del flujo y la validación previa a cada transición. Estas son las piezas clave a retener para reproducir el patrón con confianza.
- Estado local con useState para datos del formulario.
- current step derivado de StateMachineConfig.initialStep.
- StateMachineConfig con steps, views y key por paso.
- getStepView con genéricos T y B extends string.
- ComponentType con props { state, setState } como React.Dispatch>.
- Renderizado condicional del botón next según el paso.
- Validación canAdvance basada en el estado (name completo en “paso uno”, luego age en “paso dos”).
- Mensaje de alert: "You can't move forward yet".
- export default del componente y reemplazo de App por StateMachineWizard en main.
- Ajustes visuales opcionales en index.css para el estilo.
¿Qué otro flujo implementarías con una máquina de estados y pasos tipo Wizard? Comparte tu idea en los comentarios y cuéntanos por qué sería útil.