home / skills / first-fluke / fullstack-starter / component-refactoring

component-refactoring skill

/.agents/skills/component-refactoring

This skill refactors high-complexity React components using proven patterns to improve maintainability, readability, and enable effective code splitting.

npx playbooks add skill first-fluke/fullstack-starter --skill component-refactoring

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.7 KB
---
name: component-refactoring
description: Refactor high-complexity React components. Use when complexity metrics are high or to split monolithic UI.
---

# Component Refactoring Skill

Refactor high-complexity React components with proven patterns and workflows.

**Complexity Threshold**: Components with **cyclomatic complexity > 50** or **line count > 300** should be candidates for refactoring.

**Use When**:

- `bun analyze-component` shows high complexity.
- Users ask for "code splitting", "hook extraction", or "cleanup".
- A component file exceeds 300 lines of code.

## Core Refactoring Patterns

### 1. Extract Custom Hooks

**Goal**: Separate UI from State/Logic.

**Before**:

```tsx
function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    fetch('/api/users').then(data => {
      setUsers(data);
      setLoading(false);
    });
  }, []);

  if (loading) return <Spinner />;
  return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
```

**After**:

```tsx
// hooks/useUsers.ts
function useUsers() {
  return useQuery({ queryKey: ['users'], queryFn: fetchUsers });
}

// UserList.tsx
function UserList() {
  const { data: users, isLoading } = useUsers();
  if (isLoading) return <Spinner />;
  return <UserListView users={users} />;
}
```

### 2. Extract Sub-Components

**Goal**: Break down monolithic JSX.

**Before**:

```tsx
function Dashboard() {
  return (
    <div>
      <header>...</header>
      <aside>...</aside>
      <main>
        <section className="stats">...</section>
        <section className="feed">...</section>
      </main>
    </div>
  );
}
```

**After**:

```tsx
function Dashboard() {
  return (
    <Layout>
      <DashboardHeader />
      <DashboardSidebar />
      <DashboardContent>
        <StatsWidget />
        <ActivityFeed />
      </DashboardContent>
    </Layout>
  );
}
```

### 3. Simplify Conditional Logic

**Goal**: Reduce nesting and `if/else` checks implementation details.

- Use **Lookup Tables** (Maps/Objects) instead of Switch/If-Else chains.
- Use **Guard Clauses** (Early Returns) to avoid deep nesting.

### 4. Extract Modal Management

**Goal**: Centralize modal state and logic.

- Move modal definitions to a generic `<ModalManager />` or context if reused globally.
- Keep the `isOpen` state locally if specific to a single component, but extract the Modal content to a separate file.

## Workflow

1. **Analyze**: Run complexity analysis or review the file manually.
2. **Plan**: Identify seam lines (Logic vs UI, Section vs Section).
3. **Extract**: Create new files for hooks or components.
4. **Integrate**: Replace original code with imports.
5. **Verify**: Ensure functionality remains identical and tests pass.

Overview

This skill refactors high-complexity React components using proven extraction patterns and a practical workflow. It targets components with very high cyclomatic complexity or large file size to improve maintainability, testability, and performance. The focus is on splitting logic from UI, extracting hooks and sub-components, and simplifying conditionals.

How this skill works

The skill inspects component metrics (cyclomatic complexity and line count) and identifies seams between state/logic and presentational code. It recommends and performs targeted refactors: extract custom hooks for data and effects, split monolithic JSX into smaller components, centralize modal management, and replace nested conditionals with guard clauses or lookup tables. After extraction, it integrates imports, runs basic verification steps, and ensures behavior remains unchanged.

When to use it

  • When a component has cyclomatic complexity > 50 or line count > 300
  • After running a static analysis tool (e.g., bun analyze-component) that flags high complexity
  • When a single component handles both data fetching/state and extensive UI rendering
  • When planning to split a monolithic UI for reuse, testing, or performance optimization
  • When many conditional branches produce deep nesting that's hard to follow

Best practices

  • Separate concerns: move data fetching and side effects into custom hooks
  • Create small, focused sub-components for logical UI sections (header, sidebar, widgets)
  • Prefer guard clauses and lookup tables to reduce nested if/else and switch chains
  • Keep modal state local unless modals are reused across the app; otherwise use a ModalManager or context
  • Verify behavior with existing tests and add unit tests for extracted hooks and components

Example use cases

  • Refactoring a 500-line Dashboard component into Layout, Header, Sidebar, and Content components
  • Extracting a useUsers hook to encapsulate fetching, caching, and loading state for user lists
  • Replacing a large switch-based renderer with a component map to simplify rendering logic
  • Centralizing multiple modal dialogs behind a ModalManager to reduce duplicated state handling
  • Splitting a complex form component into smaller field components and a useFormHook for validation

FAQ

What complexity thresholds trigger refactoring?

Use cyclomatic complexity > 50 or file length > 300 lines as strong indicators for refactoring.

Should extracted hooks be typed?

Yes—add TypeScript types to hook inputs and return values to improve discoverability and catch regressions.