lang-react

codethread's avatarfrom codethread

Build React SPAs where components are declarative UI consuming external state (Zustand/XState/TanStack Query). Logic lives in stores, not components.

⭐0stars🔀0forks📁View on GitHub🕐Updated Nov 14, 2025⬇️1downloads

When & Why to Use This Skill

This Claude skill acts as a React Architecture Expert, specializing in building scalable Single Page Applications (SPAs) through a declarative UI philosophy. It enforces a strict separation of concerns by decoupling business logic from components and delegating state management to specialized libraries like Zustand, XState, and TanStack Query. This approach optimizes frontend performance, simplifies debugging, and ensures a highly testable codebase by focusing on logic-heavy stores rather than brittle UI components.

Use Cases

  • Architecting new React SPAs with a clean separation between declarative UI components and externalized business logic.
  • Refactoring complex legacy components by migrating 'spaghetti' logic into centralized Zustand stores or XState machines.
  • Implementing robust data fetching and caching strategies using TanStack Query to replace manual useEffect-based API calls.
  • Designing deterministic state transitions for complex user workflows and multi-step forms using XState integration.
  • Establishing a high-efficiency testing strategy that prioritizes unit testing business logic in stores over expensive and slow E2E component tests.
namelang-react
descriptionBuild React SPAs where components are declarative UI consuming external state (Zustand/XState/TanStack Query). Logic lives in stores, not components.

React Expert

Core Philosophy

Components consume external state, contain no logic:

  • External hooks at top (Zustand, XState, TanStack Query)
  • No useState/useReducer/useEffect for complex logic
  • Inline actions unless repeated 2+ times
  • Test stores/machines (unit tests), not components (E2E only)

State Management Stack

State Type Solution
Remote (REST) TanStack Query
Remote (GraphQL) Apollo Client
Application state Zustand
Complex machines XState
Local UI state useState (rare, last resort)

Component Pattern

// ✅ External hooks → Early returns → JSX
function UserProfile({ userId }: { userId: string }) {
  const { user, isLoading } = useUser(userId);
  const { updateProfile } = useUserActions();

  if (isLoading) return <Spinner />;

  return (
    <div>
      <h1>{user.name}</h1>
      <button onClick={() => updateProfile({ email: 'new@example.com' })}>
        Update
      </button>
    </div>
  );
}

Testing: Stores, Not Components

What Tool Why
Zustand stores Vitest Test without React
XState machines Vitest Deterministic transitions
Critical flows Playwright Real browser
Components Never Logic should be in stores
// Test store directly
const { login } = useAuthStore.getState();
await login({ email: "test@example.com", password: "pass" });
expect(useAuthStore.getState().user).toBeDefined();

Unique Patterns

Prop Ordering: Simple → Complex

<Table
  data={items}
  loading={isLoading}
  sortable
  onSort={handleSort}
  renderRow={(item) => <Row>{item.name}</Row>}
/>

Inline Props for Type Inference

// ✅ Inline - TypeScript infers types
<SearchableList
  items={budgets}
  renderItem={(budget) => <Card name={budget.name} />}
/>;

// ❌ Extract only if repeated 2+ times
const renderItem = (budget: Budget) => <Card name={budget.name} />;

Pattern Matching for Variants

import { match } from "ts-pattern";

{
  match(state)
    .with({ _tag: "loading" }, () => <Spinner />)
    .with({ _tag: "success" }, (s) => <Data value={s.data} />)
    .exhaustive();
}

Performance: Profile First

Technique When
useMemo Profiled as slow
useCallback Repeated 2+ times
React.memo Props rarely change
Code splitting Route-level

Styled-Components: Consolidate with CSS Selectors

// ✅ Single component with CSS selectors
const Table = styled.table`
  thead {
    background: ${(p) => p.theme.colors.header};
  }
  tbody tr:hover {
    background: ${(p) => p.theme.colors.hover};
  }
  td {
    padding: ${(p) => p.theme.space.md};
  }
`;

// ❌ Separate components for each element
const TableHeader = styled.thead`...`;
const TableRow = styled.tr`...`;
const TableCell = styled.td`...`;

Version 1.0.1