Minimize the scope of impact of code changes. A change to one feature must not break another feature.
Key Patterns
Eliminate Props Drilling (Composition Pattern)
❌ props passing through layers:
function ItemEditModal({ items, onConfirm, onClose }) {
return (
<Modal onClose={onClose}>
<ItemEditBody items={items} onConfirm={onConfirm} onClose={onClose} />
</Modal>
);
}
function ItemEditBody({ items, onConfirm, onClose }) {
return (
<>
<Button onClick={onClose}>닫기</Button>
<ItemEditList items={items} onConfirm={onConfirm} />
</>
);
}
✅ Composing with children:
function ItemEditModal({ items, onConfirm, onClose }) {
return (
<Modal onClose={onClose}>
<ItemEditBody onClose={onClose}>
<ItemEditList items={items} onConfirm={onConfirm} />
</ItemEditBody>
</Modal>
);
}
function ItemEditBody({ children, onClose }) {
return <><Button onClick={onClose}>닫기</Button>{children}</>;
}
Separation of Responsibilities
❌ A Hook that manages everything:
function usePageState() {
const [query] = useQueryParams({
cardId: NumberParam, dateFrom: DateParam, dateTo: DateParam, statusList: ArrayParam
});
}
✅ A single-responsibility Hook:
function useCardIdQueryParam() {
const [cardId, setCardId] = useQueryParam("cardId", NumberParam);
return [cardId ?? undefined, setCardId] as const;
}
Quick Reference
| Code Smell | How to Improve |
|---|---|
| props passing through 3 or more layers | Composition pattern: use children |
| A Hook returning 5 or more values | Split into single-responsibility Hooks |
| Modifying A breaks unrelated B | Identify the coupling point and introduce an interface |
| A util imported everywhere | Move it closer to its usage sites |
When Context Is Appropriate
Only for truly global concerns: theme, locale, auth state, data needed by 10 or more components.
Do not overuse Context just to avoid the composition pattern.
Exception: When Duplication Is Better
- When behavior may vary from page to page
- When the burden of testing all dependent code for a shared code change is large
Reference: https://frontend-fundamentals.com/code-quality/loosely-coupled/