Skip to main content

React Integration

Stage Flow provides seamless React integration through a comprehensive set of hooks, components, and utilities that make complex state management simple and predictable.

Overview

Stage Flow's React integration transforms your application state management from imperative to declarative. Instead of manually managing state transitions with useState and useEffect, Stage Flow gives you a declarative way to define your application's behavior.

Why Use Stage Flow with React?

  • Declarative State Management: Define your app's states and transitions in one place
  • Type Safety: Full TypeScript support with compile-time error checking
  • Predictable Behavior: Clear rules for when and how state changes occur
  • Reusable Logic: Share state logic across components
  • Better Testing: Easy to test state transitions and user flows
  • Smooth Animations: Built-in animation support with Framer Motion
  • Error Handling: Comprehensive error boundaries and recovery

Quick Start

import { StageFlowProvider, StageRenderer, useStageFlow } from '@stage-flow/react';
import { StageFlowEngine } from '@stage-flow/core';

// Define your stages and data
type AppStage = 'idle' | 'loading' | 'success' | 'error';
type AppData = { email?: string; user?: User; error?: string };

// Create your engine
const engine = new StageFlowEngine({
initial: 'idle',
stages: [
{
name: 'idle',
transitions: [{ target: 'loading', event: 'start' }]
},
{
name: 'loading',
transitions: [
{ target: 'success', event: 'complete' },
{ target: 'error', event: 'fail' }
]
},
{
name: 'success',
transitions: [{ target: 'idle', event: 'reset' }]
},
{
name: 'error',
transitions: [{ target: 'idle', event: 'retry' }]
}
]
});

// Use in your app
function App() {
return (
<StageFlowProvider engine={engine}>
<StageRenderer
stageComponents={{
idle: IdleView,
loading: LoadingView,
success: SuccessView,
error: ErrorView
}}
disableAnimations={false}
style={{ minHeight: "400px" }}
/>
</StageFlowProvider>
);
}

// Stage components receive props from StageRenderer
function IdleView({ stage, data, send, goTo, isTransitioning }) {
const handleStart = () => {
send('start');
};

return (
<div>
<h1>Welcome</h1>
<button onClick={handleStart} disabled={isTransitioning}>
{isTransitioning ? 'Starting...' : 'Start'}
</button>
</div>
);
}

function LoadingView({ stage, data, send, goTo, isTransitioning }) {
return (
<div>
<h1>Loading...</h1>
<div className="spinner" />
</div>
);
}

function SuccessView({ stage, data, send, goTo, isTransitioning }) {
const handleReset = () => {
send('reset');
};

return (
<div>
<h1>Success!</h1>
<p>Welcome, {data.user?.name}!</p>
<button onClick={handleReset}>Reset</button>
</div>
);
}

function ErrorView({ stage, data, send, goTo, isTransitioning }) {
const handleRetry = () => {
send('retry');
};

return (
<div>
<h1>Error</h1>
<p>{data.error}</p>
<button onClick={handleRetry}>Try Again</button>
</div>
);
}

Core Concepts

Components

Hooks

Advanced Patterns

Performance & Integration

What's Next?