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.
npx -y skills add yunseo-kim/agent-toolbox --skill react-refactoringAssembled 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
| Score | Level | Action |
|---|---|---|
| 0-25 | Simple | Ready for testing |
| 26-50 | Medium | Consider minor refactoring |
| 51-75 | Complex | Refactor before testing |
| 76-100 | Very Complex | Must 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 Feature | Refactoring Action |
|---|---|
Multiple useState + useEffect | Extract custom hook |
| API calls in component | Extract data/service hook |
| Many event handlers | Extract event handler logic |
| 300+ lines | Split into sub-components |
| Deep nesting / complex conditionals | Simplify conditional logic |
| Multiple modal states | Extract modal management |
Step 3: Execute Incrementally
- Extract one piece at a time
- Run lint, type-check, and tests after each extraction
- 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 patternsreferences/component-splitting.md- Component splitting strategies and directory structuresreferences/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.