The Mental Model
Same song. Cleaner mix.
A remix doesn't change the song—it changes how it sounds. Refactoring doesn't change what the code does. It changes how it reads.
Pull logic out of a component into its own function or hook.
Give variables meaningful names. d becomes userData.
A 300-line component becomes three 100-line components.
Remove unused imports, dead code, console.logs. Less is more.
Long function? Duplicated code? Unclear naming?
"Extract the fetch logic into a custom hook"
Same output, cleaner input. The remix is done.
Extract & Isolate
What Is a Custom Hook?
A custom hook is just a function that starts with use. It lets you bundle state + effects into a reusable package.
Identify repeated logic
Fetching data? Managing a form? Tracking window size?
Move it to a function
function useWindowSize() — prefix with "use".
Return what you need
return { width, height } — just like a regular hook.
The AI Prompt
Copy your messy component and tell the AI exactly what to do:
# Good refactoring prompts:
"Extract the fetch logic into a custom hook called useUsers"
"Split this component into UserList and UserCard"
"Rename all single-letter variables to descriptive names"
"Remove all unused imports and dead code"
Never say "refactor this." Be specific about what to change and how.
The Clean Room
One component, one job.
If a component does too many things, it becomes fragile. The rule of thumb: if you have to scroll to understand it, it's too long.
Split by responsibility. The parent orchestrates. The children render.
<UserPage> // orchestrator
├― useUsers() // data hook
├― <UserList> // renders the list
├― <UserCard> // single user
├― <UserCard>
└― <UserCard>
└― <EmptyState> // fallback
The AI Janitor
The Cleanup Checklist
After the rush of building, your codebase needs a cleanup pass. Give the AI each task individually—one prompt per concern.
Dead Code
"Remove all unused imports and variables"
Naming
"Rename single-letter vars to descriptive names"
Duplication
"Combine these three similar functions into one"
Organization
"Move this into a /components folder"
Types
"Add TypeScript types to this component's props"
Console Logs
"Remove all console.log statements"
The Golden Rule
"Refactor when it works. Never when it's broken."
Get it working first. Then make it clean. If you refactor broken code, you'll have clean broken code.
Common Patterns
✗ Refactor Traps
"I'll rewrite the whole thing"
Rewrites are risky. Refactor in small, testable steps instead.
"Let me add abstractions everywhere"
Premature abstraction is worse than duplication. Wait until you repeat something 3 times.
"I'll refactor and add features at the same time"
One or the other. Never both. Mixing causes bugs you can't trace.
"Just say ‘refactor this’ to the AI"
Vague prompts get vague results. Be specific about what to change.
✓ Clean Remix
One change at a time
Rename first. Extract second. Split third. Commit between each step.
Verify after every change
Does the app still work? Does the page still render? Check before continuing.
Use descriptive commit messages
"refactor: extract useUsers hook from UserPage" — clear and traceable.
Read the diff before committing
git diff shows exactly what changed. Review your own code.
The Exercises
Clean up your codebase.
The Hook
Extract Logic
- →Find a component with fetch logic
- →Ask AI to extract it into a custom hook
- →Verify the page still works
The Split
Break It Up
- →Find your longest component
- →Ask AI to split it into 2-3 smaller pieces
- →Wire them together with props
The Sweep
Delete Dead Code
- →Remove all console.log statements
- →Delete unused imports and variables
- →Rename any cryptic variable names
📋 Quick Reference Cheatsheet
Custom Hook
function useX() { return {...} }Check Diff
git diff --statCommit
refactor: [what changed]