Skip to main content
Week 05 • Track 02 • The Tool

Refactoring
Rhythms.

The code works. But it's messy. Time to remix it—same outcome, cleaner code. Use the AI to refactor without breaking anything.

messy-component.tsx

export default function Page() {

const [d, sd] = useState(null);

const [l, sl] = useState(true);

const [e, se] = useState(null);

useEffect(() => {

fetch('/api/users')

.then(r => r.json())

.then(j => { sd(j); sl(false); })

.catch(x => { se(x); sl(false); });

}, []);

// 200 more lines of mixed logic...

}

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.

Extract = Isolate the Track

Pull logic out of a component into its own function or hook.

Rename = Label the Channels

Give variables meaningful names. d becomes userData.

Split = Separate the Stems

A 300-line component becomes three 100-line components.

Delete = Cut the Dead Weight

Remove unused imports, dead code, console.logs. Less is more.

Refactoring Flow
Step 1
Identify the smell

Long function? Duplicated code? Unclear naming?

Step 2
Ask AI to refactor

"Extract the fetch logic into a custom hook"

Step 3
Verify it still works

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.

1

Identify repeated logic

Fetching data? Managing a form? Tracking window size?

2

Move it to a function

function useWindowSize() — prefix with "use".

3

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.

300 lines
UserPage.tsx
80 lines
UserPage.tsx
60 lines
UserList.tsx
45 lines
UserCard.tsx
40 lines
useUsers.ts
component-tree

<UserPage> // orchestrator

&boxvr;&horbar; useUsers() // data hook

&boxvr;&horbar; <UserList> // renders the list

&boxvr;&horbar; <UserCard> // single user

&boxvr;&horbar; <UserCard>

&boxur;&horbar; <UserCard>

&boxur;&horbar; <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.

1

Dead Code

"Remove all unused imports and variables"

2

Naming

"Rename single-letter vars to descriptive names"

3

Duplication

"Combine these three similar functions into one"

4

Organization

"Move this into a /components folder"

5

Types

"Add TypeScript types to this component's props"

6

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.

Works + messy = refactor time
Broken + messy = fix first
Works + clean = leave it alone

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.

01

The Hook

Extract Logic

  • Find a component with fetch logic
  • Ask AI to extract it into a custom hook
  • Verify the page still works
Goal: Reusable data hook
02

The Split

Break It Up

  • Find your longest component
  • Ask AI to split it into 2-3 smaller pieces
  • Wire them together with props
Goal: No file over 150 lines
03

The Sweep

Delete Dead Code

  • Remove all console.log statements
  • Delete unused imports and variables
  • Rename any cryptic variable names
Goal: Zero lint warnings

📋 Quick Reference Cheatsheet

Custom Hook

function useX() { return {...} }

Check Diff

git diff --stat

Commit

refactor: [what changed]