rn-state-flows

Complex multi-step operations in React Native. Use when implementing flows with multiple async steps, state machine patterns, or debugging flow ordering issues.

25 stars

Best use case

rn-state-flows is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Complex multi-step operations in React Native. Use when implementing flows with multiple async steps, state machine patterns, or debugging flow ordering issues.

Teams using rn-state-flows should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/rn-state-flows/SKILL.md --create-dirs "https://raw.githubusercontent.com/ComeOnOliver/skillshub/main/skills/aiskillstore/marketplace/cjharmath/rn-state-flows/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/rn-state-flows/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How rn-state-flows Compares

Feature / Agentrn-state-flowsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Complex multi-step operations in React Native. Use when implementing flows with multiple async steps, state machine patterns, or debugging flow ordering issues.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Complex State Flows

## Problem Statement

Multi-step operations with dependencies between steps are prone to ordering bugs, missing preconditions, and untested edge cases. Even without a formal state machine library, thinking in states and transitions prevents bugs.

---

## Pattern: State Machine Thinking

**Problem:** Complex flows have implicit states that aren't modeled, leading to invalid transitions.

**Example - Retake flow states:**

```
IDLE → LOADING_COMPLETED → ENABLING_RETAKE → CLEARING_ANSWERS → READY → ANSWERING → MERGING → SUBMITTING → COMPLETE
                                                                                                              ↓
                                                                                                           ERROR
```

**Each transition should have:**

1. **Preconditions** - What must be true before this step
2. **Action** - What happens during this step
3. **Postconditions** - What must be true after this step
4. **Error handling** - What to do if this step fails

```typescript
// Document the flow explicitly
/*
 * RETAKE FLOW
 * 
 * State: IDLE
 * Precondition: assessment exists
 * Action: loadCompletedAssessmentAnswers
 * Postcondition: completedAssessmentAnswers populated
 * 
 * State: LOADING_COMPLETED
 * Precondition: completedAssessmentAnswers loaded
 * Action: enableSkillAreaRetake
 * Postcondition: skillArea in retakeAreas set
 * 
 * State: ENABLING_RETAKE
 * Precondition: skillArea in retakeAreas
 * Action: clearSkillAreaAnswers
 * Postcondition: existing answers for skillArea removed
 * 
 * ... continue for each state
 */
```

---

## Pattern: Explicit Flow Implementation

**Problem:** Flow logic scattered across multiple functions, hard to verify ordering.

```typescript
// WRONG - implicit flow, easy to miss steps or misordering
async function startRetake(assessmentId: string, skillArea: string) {
  loadCompletedAssessmentAnswers(assessmentId); // Missing await!
  await enableSkillAreaRetake(skillArea);
  await clearSkillAreaAnswers(skillArea);
}

// CORRECT - explicit flow with validation
async function startRetake(assessmentId: string, skillArea: string) {
  const flowId = `retake-${Date.now()}`;
  logger.info(`[${flowId}] Starting retake flow`, { assessmentId, skillArea });
  
  // Step 1: Load completed answers
  await loadCompletedAssessmentAnswers(assessmentId);
  const completedAnswers = useStore.getState().completedAssessmentAnswers;
  if (Object.keys(completedAnswers).length === 0) {
    throw new Error(`[${flowId}] Failed to load completed answers`);
  }
  logger.debug(`[${flowId}] Loaded ${Object.keys(completedAnswers).length} answers`);
  
  // Step 2: Enable retake for skill area
  await enableSkillAreaRetake(skillArea);
  const retakeAreas = useStore.getState().retakeAreas;
  if (!retakeAreas.has(skillArea)) {
    throw new Error(`[${flowId}] Failed to enable retake for ${skillArea}`);
  }
  logger.debug(`[${flowId}] Enabled retake for ${skillArea}`);
  
  // Step 3: Clear existing answers
  await clearSkillAreaAnswers(skillArea);
  logger.debug(`[${flowId}] Cleared answers for ${skillArea}`);
  
  logger.info(`[${flowId}] Retake flow completed`);
}
```

---

## Pattern: Flow Object

**Problem:** Long async functions with many steps become unwieldy.

```typescript
interface FlowStep<TContext> {
  name: string;
  execute: (context: TContext) => Promise<void>;
  validate?: (context: TContext) => void;  // Postcondition check
}

interface RetakeContext {
  assessmentId: string;
  skillArea: string;
  flowId: string;
}

const retakeSteps: FlowStep<RetakeContext>[] = [
  {
    name: 'loadCompletedAnswers',
    execute: async (ctx) => {
      await loadCompletedAssessmentAnswers(ctx.assessmentId);
    },
    validate: (ctx) => {
      const answers = useStore.getState().completedAssessmentAnswers;
      if (Object.keys(answers).length === 0) {
        throw new Error(`[${ctx.flowId}] No completed answers loaded`);
      }
    },
  },
  {
    name: 'enableRetake',
    execute: async (ctx) => {
      await enableSkillAreaRetake(ctx.skillArea);
    },
    validate: (ctx) => {
      const retakeAreas = useStore.getState().retakeAreas;
      if (!retakeAreas.has(ctx.skillArea)) {
        throw new Error(`[${ctx.flowId}] Retake not enabled for ${ctx.skillArea}`);
      }
    },
  },
  {
    name: 'clearAnswers',
    execute: async (ctx) => {
      await clearSkillAreaAnswers(ctx.skillArea);
    },
  },
];

async function executeFlow<TContext>(
  steps: FlowStep<TContext>[],
  context: TContext,
  flowName: string
) {
  const flowId = `${flowName}-${Date.now()}`;
  logger.info(`[${flowId}] Starting flow`, context);
  
  for (const step of steps) {
    logger.debug(`[${flowId}] Executing: ${step.name}`);
    try {
      await step.execute(context);
      if (step.validate) {
        step.validate(context);
      }
      logger.debug(`[${flowId}] Completed: ${step.name}`);
    } catch (error) {
      logger.error(`[${flowId}] Failed at: ${step.name}`, { error: error.message });
      throw error;
    }
  }
  
  logger.info(`[${flowId}] Flow completed`);
}

// Usage
await executeFlow(retakeSteps, { assessmentId, skillArea, flowId }, 'retake');
```

---

## Pattern: Flow State Tracking

**Problem:** Components need to know current flow state for UI feedback.

```typescript
type RetakeFlowState =
  | { status: 'idle' }
  | { status: 'loading'; step: string }
  | { status: 'ready' }
  | { status: 'answering'; answeredCount: number }
  | { status: 'submitting' }
  | { status: 'complete' }
  | { status: 'error'; message: string; step: string };

const useRetakeStore = create<{
  flowState: RetakeFlowState;
  setFlowState: (state: RetakeFlowState) => void;
}>((set) => ({
  flowState: { status: 'idle' },
  setFlowState: (flowState) => set({ flowState }),
}));

async function startRetake(assessmentId: string, skillArea: string) {
  const { setFlowState } = useRetakeStore.getState();
  
  try {
    setFlowState({ status: 'loading', step: 'loadingAnswers' });
    await loadCompletedAssessmentAnswers(assessmentId);
    
    setFlowState({ status: 'loading', step: 'enablingRetake' });
    await enableSkillAreaRetake(skillArea);
    
    setFlowState({ status: 'loading', step: 'clearingAnswers' });
    await clearSkillAreaAnswers(skillArea);
    
    setFlowState({ status: 'ready' });
  } catch (error) {
    setFlowState({ 
      status: 'error', 
      message: error.message,
      step: useRetakeStore.getState().flowState.step,
    });
  }
}

// Component usage
function RetakeScreen() {
  const flowState = useRetakeStore((s) => s.flowState);
  
  if (flowState.status === 'loading') {
    return <Loading step={flowState.step} />;
  }
  
  if (flowState.status === 'error') {
    return <Error message={flowState.message} step={flowState.step} />;
  }
  
  // ... render based on state
}
```

---

## Pattern: Integration Testing Flows

**Problem:** Unit tests for individual functions don't catch flow-level bugs.

```typescript
describe('Retake Flow', () => {
  beforeEach(() => {
    useAssessmentStore.getState()._reset();
  });

  it('persists answers through complete retake flow', async () => {
    const assessmentId = 'test-assessment';
    const skillArea = 'fundamentals';
    const store = useAssessmentStore;
    
    // Setup: Simulate existing completed assessment
    store.getState().setCompletedAnswers(assessmentId, mockCompletedAnswers);
    
    // Execute full flow
    await store.getState().loadCompletedAssessmentAnswers(assessmentId);
    
    // Verify postcondition
    expect(Object.keys(store.getState().completedAssessmentAnswers).length)
      .toBeGreaterThan(0);
    
    await store.getState().enableSkillAreaRetake(skillArea);
    
    // Verify postcondition
    expect(store.getState().retakeAreas.has(skillArea)).toBe(true);
    
    await store.getState().clearSkillAreaAnswers(skillArea);
    
    // Simulate user answering
    await store.getState().saveAnswer('q1', 4);
    
    // THE CRITICAL CHECK - does the answer persist?
    expect(store.getState().userAnswers['q1']).toBe(4);
    
    // Complete flow
    await store.getState().submitRetake(assessmentId);
    
    // Verify final state
    expect(store.getState().flowState.status).toBe('complete');
  });

  it('handles error at each step', async () => {
    // Test error handling at step 1
    mockApi.loadAnswers.mockRejectedValueOnce(new Error('Network error'));
    
    await expect(
      store.getState().startRetake(assessmentId, skillArea)
    ).rejects.toThrow('Network error');
    
    expect(store.getState().flowState.status).toBe('error');
    expect(store.getState().flowState.step).toBe('loadingAnswers');
  });
});
```

---

## Pattern: Flow Documentation

Document complex flows with diagrams for team understanding:

```markdown
## Retake Flow

### Happy Path

```
┌─────────┐     ┌──────────────┐     ┌───────────────┐     ┌───────────────┐
│  Start  │────▶│ Load Answers │────▶│ Enable Retake │────▶│ Clear Answers │
└─────────┘     └──────────────┘     └───────────────┘     └───────────────┘
                       │                     │                     │
                       ▼                     ▼                     ▼
                 Postcondition:        Postcondition:         Postcondition:
                 answers.length > 0    retakeAreas.has(x)    cleared for area

                                                                   │
                                                                   ▼
┌──────────┐     ┌─────────┐     ┌───────────────┐     ┌──────────────────┐
│ Complete │◀────│ Merge   │◀────│ User Answers  │◀────│ Ready for Input  │
└──────────┘     └─────────┘     └───────────────┘     └──────────────────┘
```

### Error States

Any step can fail → transition to ERROR state with step context.
From ERROR: user can retry (back to IDLE) or exit.
```

---

## Checklist: Designing Complex Flows

Before implementing:

- [ ] Sketch state diagram (even on paper)
- [ ] Identify all states, including error states
- [ ] Document preconditions for each transition
- [ ] Document postconditions to verify
- [ ] Plan how to surface state to UI

During implementation:

- [ ] Verify preconditions before each step
- [ ] Validate postconditions after each step
- [ ] Log state transitions with flow ID
- [ ] Handle errors at each step with context
- [ ] Surface flow state for UI feedback

After implementation:

- [ ] Integration test for happy path
- [ ] Integration test for error at each step
- [ ] Verify logs are sufficient for debugging
- [ ] Document flow for team

---

## When to Use XState

Consider XState when:

- Flow has > 6 states
- Complex branching/parallel states
- Need visualization/debugging tools
- State machine is shared across team

For simpler flows, explicit steps with validation (as shown above) are often sufficient and more readable.

Related Skills

terraform-state-manager

25
from ComeOnOliver/skillshub

Terraform State Manager - Auto-activating skill for DevOps Advanced. Triggers on: terraform state manager, terraform state manager Part of the DevOps Advanced skill category.

mermaid-state-diagram-creator

25
from ComeOnOliver/skillshub

Mermaid State Diagram Creator - Auto-activating skill for Visual Content. Triggers on: mermaid state diagram creator, mermaid state diagram creator Part of the Visual Content skill category.

building-gitops-workflows

25
from ComeOnOliver/skillshub

This skill enables Claude to construct GitOps workflows using ArgoCD and Flux. It is designed to generate production-ready configurations, implement best practices, and ensure a security-first approach for Kubernetes deployments. Use this skill when the user explicitly requests "GitOps workflow", "ArgoCD", "Flux", or asks for help with setting up a continuous delivery pipeline using GitOps principles. The skill will generate the necessary configuration files and setup code based on the user's specific requirements and infrastructure.

cursor-composer-workflows

25
from ComeOnOliver/skillshub

Master Cursor Composer for multi-file AI editing, scaffolding, and refactoring. Triggers on "cursor composer", "multi-file edit", "cursor generate files", "composer workflow", "cursor scaffold", "Cmd+I".

flowstudio-power-automate-mcp

25
from ComeOnOliver/skillshub

Connect to and operate Power Automate cloud flows via a FlowStudio MCP server. Use when asked to: list flows, read a flow definition, check run history, inspect action outputs, resubmit a run, cancel a running flow, view connections, get a trigger URL, validate a definition, monitor flow health, or any task that requires talking to the Power Automate API through an MCP tool. Also use for Power Platform environment discovery and connection management. Requires a FlowStudio MCP subscription or compatible server — see https://mcp.flowstudio.app

flowstudio-power-automate-debug

25
from ComeOnOliver/skillshub

Debug failing Power Automate cloud flows using the FlowStudio MCP server. Load this skill when asked to: debug a flow, investigate a failed run, why is this flow failing, inspect action outputs, find the root cause of a flow error, fix a broken Power Automate flow, diagnose a timeout, trace a DynamicOperationRequestFailure, check connector auth errors, read error details from a run, or troubleshoot expression failures. Requires a FlowStudio MCP subscription — see https://mcp.flowstudio.app

flowstudio-power-automate-build

25
from ComeOnOliver/skillshub

Build, scaffold, and deploy Power Automate cloud flows using the FlowStudio MCP server. Load this skill when asked to: create a flow, build a new flow, deploy a flow definition, scaffold a Power Automate workflow, construct a flow JSON, update an existing flow's actions, patch a flow definition, add actions to a flow, wire up connections, or generate a workflow definition from scratch. Requires a FlowStudio MCP subscription — see https://mcp.flowstudio.app

tdd-workflows-tdd-refactor

25
from ComeOnOliver/skillshub

Use when working with tdd workflows tdd refactor

tdd-workflows-tdd-red

25
from ComeOnOliver/skillshub

Generate failing tests for the TDD red phase to define expected behavior and edge cases.

tdd-workflows-tdd-green

25
from ComeOnOliver/skillshub

Implement the minimal code needed to make failing tests pass in the TDD green phase.

tdd-workflows-tdd-cycle

25
from ComeOnOliver/skillshub

Use when working with tdd workflows tdd cycle

git-pr-workflows-pr-enhance

25
from ComeOnOliver/skillshub

You are a PR optimization expert specializing in creating high-quality pull requests that facilitate efficient code reviews. Generate comprehensive PR descriptions, automate review processes, and ensu