- Home
- Skills
- Frontend & Web Apps
- React Component State Machine Outliner
Works with the AI Agents you already use
React Component State Machine Outliner
Architect complex React component logic with exhaustive XState machine mapping and transition outlines.
$5
React Component State Machine Outliner
Example session with this skill installed
Feature Description: A multi-step checkout wizard with a cart review step, shipping address form, payment processing, and success confirmation. Key Requirements/Edge Cases: The user must be able to go back to previous steps without losing data. Payment processing can fail and should allow 3 retries before locking the session.
- Read your context and instructions
- Compiled the react component state
1. Machine Overview
A multi-step checkout wizard that moves a user through
cart review → shipping address → payment → success. It supports non-destructive backward navigation (all entered data lives in context and survives step changes) and a payment retry policy: a failed payment can be retried up to 3 times, after which the session is locked and no further payment attempts are possible.
Scope: step navigation, form data retention, payment invocation and failure handling, retry counting, session locking. Out of scope: field-level input validation UI (handled by form libraries), cart editing, and payment-provider UI internals.
2. Context (Extended State)
interface CheckoutContext {
cart: {
items: Array<{ id: string; name: string; qty: number; unitPrice: number }>;
subtotal: number;
};
shippingAddress: {
fullName: string;
line1: string;
line2?: string;
city: string;
state: string;
postalCode: string;
country: string;
phone?: string;
} | null;
paymentDetails: {
method: 'card' | 'upi' | 'wallet';
token: string; // tokenized reference only, never raw card data
billingSameAsShipping: boolean;
} | null;
paymentAttempts: number; // starts at 0, max 3
maxPaymentAttempts: number; // constant 3
lastError: { code: string; message: string } | null;
orderId: string | null;
lockedReason: string | null;
}
3. Events
NEXT: advance from the current step (payload: none; relies on context already updated)BACK: return to the previous step (no payload)UPDATE_CART:{ items: CartItem[] }, sync cart changes in from the outsideUPDATE_SHIPPING:{ address: ShippingAddress }, save form data without leaving the stepSUBMIT_SHIPPING:{ address: ShippingAddress }, save and advanceUPDATE_PAYMENT:{ details: PaymentDetails }, save payment form dataSUBMIT_PAYMENT:{ details: PaymentDetails }, save and start processingRETRY_PAYMENT: no payload, retry after a failureEDIT_PAYMENT: no payload, return to the payment form after a failure to change detailsRESET: no payload, start a new checkout (only fromsuccessorlocked, per product decision)
Internal (invoked actor) events: done.invoke.processPayment (output: { orderId }) and error.platform.processPayment (error: { code, message }).
4. State Diagram Outline
-
State:
checkout(root)- Type: compound (parent of the wizard steps; holds the history-preserving behavior)
- On
RESET: Transitions tocheckout.cartReview(Guard: none; actionresetContext) - Entry Actions: none
- Exit Actions: none
-
State:
checkout.cartReview- Type: initial
- On
UPDATE_CART: Stays (action:assignCart) - On
NEXT: Transitions toshippingAddress(Guard:cartHasItems) - Entry Actions:
trackStepViewed('cart') - Exit Actions: none
-
State:
checkout.shippingAddress- Type: atomic
- On
UPDATE_SHIPPING: Stays (action:assignShipping) - On
SUBMIT_SHIPPING: Transitions topayment(Guard:isShippingValid; action:assignShipping) - On
BACK: Transitions tocartReview(no guard; context untouched) - Entry Actions:
trackStepViewed('shipping') - Exit Actions: none (data already persisted via
UPDATE_SHIPPING)
-
State:
checkout.payment- Type: compound (parent of the payment sub-states)
- Initial child:
form
On BACK: Transitions to shippingAddress (Guard: not isProcessing, enforced by only handling BACK on the form child, not on processing)
-
Entry Actions:
trackStepViewed('payment') -
Exit Actions: none
-
State:
checkout.payment.form- Type: atomic
- On
UPDATE_PAYMENT: Stays (action:assignPayment)
On SUBMIT_PAYMENT: Transitions to processing (Guard: isPaymentValid; actions: assignPayment, incrementAttempts)
- On BACK: Transitions to shippingAddress
- Entry Actions: none
- Exit Actions: none
- State:
checkout.payment.processing- Type: atomic (invokes
processPaymentactor) - Invoke:
processPaymentwith input{ cart, shippingAddress, paymentDetails } - On
done.invoke.processPayment: Transitions tosuccess(action:assignOrderId) - On
error.platform.processPayment: Transitions tofailed(action:assignError)
- Type: atomic (invokes
On BACK / NEXT / SUBMIT_PAYMENT: Ignored (no handler, which prevents double submission and mid-flight navigation)
- Entry Actions: showProcessingOverlay, clearLastError
- Exit Actions: hideProcessingOverlay
- State:
checkout.payment.failed- Type: atomic (transient decision point)
- Always (eventless transitions), evaluated in order:
- Transitions to
#checkout.locked(Guard:attemptsExhausted, i.e.paymentAttempts >= maxPaymentAttempts; action:assignLockReason) - Otherwise stays and waits for user events
- Transitions to
On RETRY_PAYMENT: Transitions to processing (Guard: canRetry, i.e. paymentAttempts < maxPaymentAttempts; action: incrementAttempts)
- On EDIT_PAYMENT: Transitions to form (Guard: canRetry)
- On BACK: Transitions to form (Guard: canRetry)
- Entry Actions: showPaymentErrorBanner, trackPaymentFailure
- Exit Actions: dismissPaymentErrorBanner
- State:
checkout.success- Type: final
- On
RESET: Transitions tocartReview(action:resetContext)
Entry Actions: clearPaymentDetails (purge token from context), trackOrderCompleted, clearPersistedCheckout
-
Exit Actions: none
-
Note: no
BACKhandler, so the user cannot return to payment after a completed order. -
State:
checkout.locked- Type: final (terminal for this session)
On RESET: Transitions to cartReview (Guard: lockExpired or an explicit support/new-session policy; action: resetContext)
Entry Actions: clearPaymentDetails, showLockedMessage, notifyBackend('session_locked'), trackSessionLocked
- Exit Actions: none
- Note: all payment events are intentionally unhandled here.
Attempt counting note: incrementAttempts runs on every transition into processing (first submit and each retry), so after the third failed attempt paymentAttempts === 3, the attemptsExhausted guard passes, and the session locks. If your product definition is "initial try plus 3 retries" (4 total), set maxPaymentAttempts to 4.
5. Implementation Notes
Keep step data in context, not in component state. Because every UPDATE_* event writes to context, the BACK transitions need no special logic and no history state. Components should read defaults from snapshot.context so returning to a step repopulates the form. For refresh resilience, persist the snapshot with actor.getPersistedSnapshot() to sessionStorage and rehydrate via createActor(machine, { snapshot }). Exclude paymentDetails.token from persistence.
-
Model the payment call as an invoked actor with
fromPromise. Usesetup({ types, guards, actions, actors })for typed XState v5 code, e.g.processPayment: fromPromise(({ input, signal }) => api.pay(input, { signal })), and pass an idempotency key (derive it fromcartplus the attempt number) so a retry after a network timeout cannot double-charge. BecauseprocessingignoresBACK, double submits and mid-flight navigation are impossible by construction; also disable the buttons fromsnapshot.matches({ payment: 'processing' }). -
Drive the UI from
snapshot.matchesand derive flags with selectors. UseuseSelector(actor, s => s.matches(...))to render each step, and compute values likeattemptsRemaining = max - paymentAttemptsfor the retry banner. Enforce the lock server-side as well (notifyBackend('session_locked')), because a client-side lock can be bypassed by reloading or clearing storage.
Connects securely to your tools. The creator never sees your data.
About this skill
Architecting complex UI logic in React often leads to "boolean soup" where dozens of useState hooks create impossible-to-debug edge cases. This skill eliminates logic errors by mapping out a formal XState machine architecture before you write a single line of component code.
What it does
- State mapping identifies all resting, loading, error, and transitional states to prevent unreachable UI configurations.
- Transition logic defines exactly which user actions or system triggers move the component between specific states.
- Context modeling outlines the extended state and data types required to track component data.
- Guard specification documents conditional logic and business rules required for state transitions.
- Side effect planning maps entry and exit actions for data fetching, logging, or DOM interactions.
How it works
- Provide a detailed description of the UI feature and its intended behavior.
- Supply any specific edge cases or business requirements that must be handled.
- Review the generated machine overview and context schema.
- Use the state diagram outline to implement the logic in XState v5.
Frameworks & tools
Specifically designed for React applications using XState v5. It generates architecture compatible with @xstate/react and the Stately editor.
Why this beats prompting it yourself
Generic LLM prompts often miss intermediate transitional states or fail to account for complex guards, leading to "halted" machines. This skill uses a structured architectural pattern that forces the agent to account for every possible event-state pair, ensuring your finite state machine is actually finite and exhaustive.
Use cases
- Designing multi-step checkout flows with complex validation and payment states.
- Architecting data-intensive dashboards with nested loading and filtering logic.
- Building robust modal and overlay systems that handle interruptions and errors.
- Modeling intricate drag-and-drop or drawing tool interactions.
Known limitations
Does not output executable TypeScript code or machine factory functions directly. It provides the architectural blueprint that the developer must then implement into a machine definition file.
How to use
Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill passes our trust checks below.
Security scanned
Passed our 8-point scan before listing
Fresh listing
Recently published to Agensi
Money-back guarantee
Doesn't do what its page promises? You get your money back.
Trust & safety
Security scanned
Verified clean 3 days ago
- Passed all security checks, Safe to install