agentsclimarketplace

React refactoring

Skill yunseo-kim/agent-toolbox/catalog/skills/react-refactoring

A trusted, curated cross-tool registry for agent components, with end-to-end provenance and automated security vetting of skills, MCP servers, and hooks.

Install
npx -y skills add yunseo-kim/agent-toolbox --skill react-refactoring

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Refactor high-complexity React components using proven patterns for hook extraction, component splitting, conditional simplification, and API/data layer separation. Use when components exceed 300 lines, have deep nesting, mix business logic with UI, or manage too many state variables. Avoid for simple or well-structured components.

The file declares its own license as Sustainable Use License 1.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

9.7 KB, as published. Nobody here has run it

React Component Refactoring

Refactor high-complexity React components using the patterns and workflow below.

Quick Reference

Complexity Score Interpretation

ScoreLevelAction
0-25SimpleReady for testing
26-50MediumConsider minor refactoring
51-75ComplexRefactor before testing
76-100Very ComplexMust refactor

Use any complexity analysis tool (SonarQube, ESLint complexity rules, or manual assessment) to gauge component complexity. Components with complexity > 50 or line count > 300 are prime refactoring candidates.

Core Refactoring Patterns

Pattern 1: Extract Custom Hooks

When: Component has complex state management, multiple useState/useEffect, or business logic mixed with UI.

Convention: Place hooks in a hooks/ subdirectory or alongside the component as use-<feature>.ts.

// Before: Complex state logic in component
const Configuration: FC = () => {
  const [modelConfig, setModelConfig] = useState<ModelConfig>(...)
  const [datasetConfigs, setDatasetConfigs] = useState<DatasetConfigs>(...)
  const [completionParams, setCompletionParams] = useState<FormValue>({})

  // 50+ lines of state management logic...

  return <div>...</div>
}

// After: Extract to custom hook
// hooks/use-model-config.ts
export const useModelConfig = (id: string) => {
  const [modelConfig, setModelConfig] = useState<ModelConfig>(...)
  const [completionParams, setCompletionParams] = useState<FormValue>({})

  // Related state management logic here

  return { modelConfig, setModelConfig, completionParams, setCompletionParams }
}

// Component becomes cleaner
const Configuration: FC = () => {
  const { modelConfig, setModelConfig } = useModelConfig(id)
  return <div>...</div>
}

Pattern 2: Extract Sub-Components

When: Single component has multiple UI sections, conditional rendering blocks, or repeated patterns.

Convention: Place sub-components in subdirectories or as separate files in the same directory.

// Before: Monolithic JSX with multiple sections
const AppInfo = () => {
  return (
    <div>
      {/* 100 lines of header UI */}
      {/* 100 lines of operations UI */}
      {/* 100 lines of modals */}
    </div>
  )
}

// After: Split into focused components
// app-info/
//   index.tsx           (orchestration only)
//   app-header.tsx      (header UI)
//   app-operations.tsx  (operations UI)
//   app-modals.tsx      (modal management)

const AppInfo = () => {
  const { showModal, setShowModal } = useAppInfoModals()

  return (
    <div>
      <AppHeader appDetail={appDetail} />
      <AppOperations onAction={handleAction} />
      <AppModals show={showModal} onClose={() => setShowModal(null)} />
    </div>
  )
}

Pattern 3: Simplify Conditional Logic

When: Deep nesting (> 3 levels), complex ternaries, or multiple if/else chains.

// Before: Deeply nested conditionals
const Template = useMemo(() => {
  if (mode === Mode.CHAT) {
    switch (locale) {
      case 'zh': return <TemplateChatZh />
      case 'ja': return <TemplateChatJa />
      default:   return <TemplateChatEn />
    }
  }
  if (mode === Mode.ADVANCED) {
    // Another 15 lines...
  }
  // More conditions...
}, [mode, locale])

// After: Use lookup tables + early returns
const TEMPLATE_MAP = {
  [Mode.CHAT]: {
    zh: TemplateChatZh,
    ja: TemplateChatJa,
    default: TemplateChatEn,
  },
  [Mode.ADVANCED]: {
    zh: TemplateAdvancedZh,
    default: TemplateAdvancedEn,
  },
}

const Template = useMemo(() => {
  const modeTemplates = TEMPLATE_MAP[mode]
  if (!modeTemplates) return null

  const TemplateComponent = modeTemplates[locale] || modeTemplates.default
  return <TemplateComponent />
}, [mode, locale])

Pattern 4: Extract API/Data Logic

When: Component directly handles API calls, data transformation, or complex async operations.

Convention: Use React Query hooks or custom data hooks to separate fetching from rendering.

// Before: API logic in component
const ServiceCard = () => {
  const [config, setConfig] = useState({})

  useEffect(() => {
    if (isActive && id) {
      (async () => {
        const res = await fetchDetail({ url: '/items', id })
        setConfig(res?.config || {})
      })()
    }
  }, [id, isActive])
}

// After: Extract to data hook using React Query
// use-item-config.ts
export const useItemConfig = (id: string, enabled: boolean) => {
  return useQuery({
    enabled: enabled && !!id,
    queryKey: ['itemConfig', 'detail', id],
    queryFn: () => get<ItemDetailResponse>(`/items/${id}`),
    select: data => data?.config || {},
  })
}

// Component becomes cleaner
const ServiceCard = () => {
  const { data: config, isLoading } = useItemConfig(id, isActive)
  // UI only
}

Pattern 5: Extract Modal/Dialog Management

When: Component manages multiple modals with complex open/close states.

// Before: Multiple modal states in component
const AppInfo = () => {
  const [showEditModal, setShowEditModal] = useState(false)
  const [showDuplicateModal, setShowDuplicateModal] = useState(false)
  const [showConfirmDelete, setShowConfirmDelete] = useState(false)
  const [showSwitchModal, setShowSwitchModal] = useState(false)
  // 5+ more modal states...
}

// After: Extract to modal management hook
type ModalType = 'edit' | 'duplicate' | 'delete' | 'switch' | null

const useModalState = () => {
  const [activeModal, setActiveModal] = useState<ModalType>(null)

  const openModal = useCallback((type: ModalType) => setActiveModal(type), [])
  const closeModal = useCallback(() => setActiveModal(null), [])

  return {
    activeModal,
    openModal,
    closeModal,
    isOpen: (type: ModalType) => activeModal === type,
  }
}

Pattern 6: Extract Form Logic

When: Complex form validation, submission handling, or field transformation.

Convention: Use a form library (@tanstack/react-form, react-hook-form) or extract to a custom hook.

// After: Extract to form hook
const useConfigForm = (initialValues: ConfigFormValues) => {
  const [values, setValues] = useState(initialValues)
  const [errors, setErrors] = useState<Record<string, string>>({})
  const [isSubmitting, setIsSubmitting] = useState(false)

  const validate = useCallback(() => {
    const newErrors: Record<string, string> = {}
    if (!values.name) newErrors.name = 'Name is required'
    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }, [values])

  const handleSubmit = useCallback(
    async (onSubmit: (values: ConfigFormValues) => Promise<void>) => {
      if (!validate()) return
      setIsSubmitting(true)
      try { await onSubmit(values) } finally { setIsSubmitting(false) }
    },
    [values, validate],
  )

  return { values, errors, isSubmitting, handleChange: setValues, handleSubmit }
}

Refactoring Workflow

Step 1: Assess Complexity

Identify:

  • Total complexity score (target < 50)
  • Max function complexity (target < 30)
  • Line count (target < 300)
  • Features detected (state, effects, API calls, modals, forms)

Step 2: Plan

Create a refactoring plan based on detected features:

Detected FeatureRefactoring Action
Multiple useState + useEffectExtract custom hook
API calls in componentExtract data/service hook
Many event handlersExtract event handler logic
300+ linesSplit into sub-components
Deep nesting / complex conditionalsSimplify conditional logic
Multiple modal statesExtract modal management

Step 3: Execute Incrementally

  1. Extract one piece at a time
  2. Run lint, type-check, and tests after each extraction
  3. Verify functionality before next step
For each extraction:
  1. Extract code
  2. Run lint and type-check
  3. Run tests
  4. Test functionality manually
  5. PASS? -> Next extraction
     FAIL? -> Fix before continuing

Step 4: Verify

After refactoring, confirm:

  • Complexity < 50 and lines < 300
  • All tests still pass
  • No new type errors
  • Functionality unchanged

Common Mistakes to Avoid

Over-Engineering

// Too many tiny hooks
const useButtonText = () => useState('Click')
const useButtonDisabled = () => useState(false)

// Cohesive hook with related state
const useButtonState = () => {
  const [text, setText] = useState('Click')
  const [disabled, setDisabled] = useState(false)
  const [loading, setLoading] = useState(false)
  return { text, setText, disabled, setDisabled, loading, setLoading }
}

Breaking Existing Patterns

  • Follow existing directory structures in your project
  • Maintain naming conventions
  • Preserve export patterns for compatibility

Premature Abstraction

  • Only extract when there's clear complexity benefit
  • Don't create abstractions for single-use code
  • Keep refactored code in the same domain area

References

  • references/complexity-patterns.md - Detailed complexity reduction patterns
  • references/component-splitting.md - Component splitting strategies and directory structures
  • references/hook-extraction.md - Hook extraction process and common hook patterns

Gives 0 of the 12 instructions most refactoring skills give

Counted across 521 of the 525 authors here whose files we hold, read 2026-08-06

  • run tests after each changein 59 of 521, across 56 files
  • write tests before refactoringin 27 of 521, across 24 files
  • preserve external behaviorin 26 of 521, across 22 files
  • remove dead codein 25 of 521, across 24 files
  • make small incremental changesin 20 of 521, across 17 files
  • break the implementation into tiny commitsin 18 of 521, across 5 files
  • ask the user about alternative optionsin 17 of 521, across 4 files
  • create a GitHub issue with the planin 17 of 521, across 4 files
  • explore the repository to verify assertionsin 17 of 521, across 4 files
  • interview the user about the refactorin 16 of 521, across 3 files
  • check the codebase for test coveragein 16 of 521, across 3 files
  • refactor one thing at a timein 16 of 521, across 12 files

Said here and by no other author read

  • target a line count below 300 per component
  • extract custom hooks for complex state management
  • extract sub-components for monolithic JSX sections
  • use lookup tables to simplify deep conditional logic
  • extract API calls to dedicated data hooks
  • consolidate multiple modal states into a single hook

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.