Understanding Code Smells: Bloaters and How to Refactor Them
# Refactoring Code Smells: Understanding and Fixing Bloaters (React + FAANG-Level Depth)
Clean code is not about writing less code — it’s about writing maintainable, scalable, and readable code. One of the most common categories of code smells is **Bloaters**.
In this deep-dive guide, we’ll:
- Understand what Bloaters are
- Explore common bloater smells
- Refactor them using JavaScript / TypeScript
- Apply improvements in React
- Discuss interview-level insights
- Approach the topic with FAANG-level engineering thinking
---
# What Are Code Smells?
Code smells are structural indicators in code that suggest deeper problems. They don’t necessarily break functionality, but they:
- Increase cognitive load
- Slow down development
- Increase bug probability
- Accumulate technical debt
Refactoring removes these smells without changing external behavior.
---
# What Are Bloaters?
Bloaters are code smells that grow excessively large over time. They make systems rigid and harder to modify.
Common types:
1. Long Method
2. Large Class
3. Primitive Obsession
4. Long Parameter List
5. Data Clumps
Let’s break them down with real examples.
---
# 1️⃣ Long Method
## ❌ Problem
A method that tries to do too much.
### Bad Example (React + TypeScript)
```tsx
const handleCheckout = async () => {
if (!cart.length) {
alert("Cart is empty");
return;
}
let total = 0;
cart.forEach(item => {
total += item.price * item.quantity;
});
if (user.isPremium) {
total *= 0.9;
}
try {
const response = await fetch("/api/checkout", {
method: "POST",
body: JSON.stringify({ total }),
});
const data = await response.json();
if (data.success) {
setOrderComplete(true);
} else {
alert("Payment failed");
}
} catch (error) {
console.error(error);
}
};
🚨 Why This Is a Bloater
- Multiple responsibilities
- Hard to test
- Hard to reuse logic
- Hard to maintain
✅ Refactored Version
const calculateTotal = (cart: CartItem[], isPremium: boolean): number => {
const subtotal = cart.reduce(
(sum, item) => sum + item.price * item.quantity,
0
);
return isPremium ? subtotal * 0.9 : subtotal;
};
const processPayment = async (total: number) => {
const response = await fetch("/api/checkout", {
method: "POST",
body: JSON.stringify({ total }),
});
return response.json();
};
const handleCheckout = async () => {
if (!cart.length) return alert("Cart is empty");
const total = calculateTotal(cart, user.isPremium);
try {
const data = await processPayment(total);
setOrderComplete(data.success);
} catch (error) {
console.error("Payment error:", error);
}
};
🎯 Improvements
- Single Responsibility Principle
- Testable functions
- Reusable business logic
- Cleaner React component
2️⃣ Large Component (Large Class Equivalent in React)
❌ Problem
A React component that handles:
- UI
- API calls
- Business logic
- State management
- Data transformation
Example:
const Dashboard = () => {
const [users, setUsers] = useState([]);
const [filtered, setFiltered] = useState([]);
useEffect(() => {
fetch("/api/users")
.then(res => res.json())
.then(data => {
setUsers(data);
setFiltered(data.filter(u => u.active));
});
}, []);
const handleSort = () => {
setFiltered([...filtered].sort((a, b) => a.name.localeCompare(b.name)));
};
return (
<div>
<button onClick={handleSort}>Sort</button>
{filtered.map(user => (
<div key={user.id}>{user.name}</div>
))}
</div>
);
};
✅ Refactored (FAANG-Style Separation)
Custom Hook
const useUsers = () => {
const [users, setUsers] = useState<User[]>([]);
useEffect(() => {
fetch("/api/users")
.then(res => res.json())
.then(setUsers);
}, []);
return users;
};
Utility Function
const getActiveUsers = (users: User[]) =>
users.filter(user => user.active);
Presentation Component
const Dashboard = () => {
const users = useUsers();
const activeUsers = getActiveUsers(users);
return (
<UserList users={activeUsers} />
);
};
🎯 Result
- Cleaner architecture
- Logic separated
- Better scalability
- Easier to test
This is how large companies structure UI systems.
3️⃣ Primitive Obsession
❌ Problem
Using primitive types instead of domain models.
type Order = {
userId: string;
amount: number;
currency: string;
};
This spreads logic everywhere.
✅ Replace Primitive with Value Object
class Money {
constructor(
public amount: number,
public currency: string
) {}
applyDiscount(percent: number) {
return new Money(this.amount * (1 - percent), this.currency);
}
}
Now:
const price = new Money(100, "USD");
const discounted = price.applyDiscount(0.1);
🎯 Why This Matters in Interviews
- Shows domain modeling skills
- Shows abstraction thinking
- Shows clean architecture mindset
4️⃣ Long Parameter List
❌ Problem
createUser(
name: string,
email: string,
age: number,
role: string,
isActive: boolean,
createdAt: Date
);
Hard to read, easy to misuse.
✅ Introduce Parameter Object
type CreateUserParams = {
name: string;
email: string;
age: number;
role: string;
isActive: boolean;
createdAt: Date;
};
createUser(params: CreateUserParams);
Cleaner, scalable, safer.
FAANG-Level Engineering Perspective
Senior engineers look beyond syntax.
They think about:
- Change frequency
- Scalability
- Team velocity
- Testability
- Cognitive load
Refactoring bloaters improves:
- Code review speed
- Onboarding time
- Bug reduction
- Feature delivery velocity
Interview-Focused Takeaways
If asked:
"How do you handle messy code?"
You can say:
- Identify code smells
- Categorize them (Bloaters, Couplers, Dispensables)
- Apply targeted refactoring patterns
- Ensure behavior remains unchanged
- Add tests if missing
This shows structured thinking.
Practical Refactoring Strategy
- Write tests first
- Extract smallest safe units
- Refactor incrementally
- Avoid rewriting everything
- Use linting & static analysis tools
Final Thoughts
Bloaters don’t appear overnight.
They grow silently.
Refactoring is not about perfection. It’s about reducing future complexity.
In modern React applications, managing bloaters is critical for:
- Performance
- Maintainability
- Scalability
- Team productivity
If you want to operate at FAANG-level engineering depth, mastering refactoring is non-negotiable.
Clean code is not aesthetic.
It’s strategic.
What did you think?