Kaynak: Dev.to · 6 dk okuma · Yazar: Gavin Cettolo
Last week I opened a React component… and immediately closed it. Not because it was complex. But...
You know that feeling: the file keeps scrolling, props are flying around, and every small change feels like it might break something completely unrelated.
And if you’ve been building UIs for a while, you’ve probably seen it happen slowly, almost invisibly.
Table of Contents
Until one day you open a file and realize you don’t really understand it anymore.
And the cost of touching the code becomes higher than leaving it alone.
The Problem with “It Still Works”
It handles data, UI, state, events, and probably a few side effects too.
tsx
export default function Dashboard({ user, posts }: Props) {
// fetching logic
// filtering logic
// UI rendering
// event handlers
// conditionals everywhere
1. The God Component (Too Big to Understand)
return (
{user.name}
{/ hundreds of lines /}
)
}
You don’t know what’s safe to change and what might break something else.
2. Props Drilling Everywhere
tsx
export function Dashboard() {
return (
)
}
You pass user from a parent to a child, then to another child, then another.
3. Confusing Responsibilities
tsx
A better approach is to use it intentionally, when it actually solves a real problem:
4. UI Logic Duplication
function UserAvatar() {
const user = useUser()
return
}
It’s not about how much code there is, but about what kind of work is happening in the same place.
5. Conditional Rendering Hell
Separating responsibilities makes the code easier to navigate and easier to trust.
Extracting shared logic is less about abstraction and more about centralizing decisions.
Using Guard Clauses
tsx
function DataState({ loading, error, children }: Props) {
if (loading) return
if (error) return
return children
}
tsx
return isAdmin
? isActive
?
:
:
Bonus Signs You Shouldn’t Ignore
tsx
function renderContent() {
if (isAdmin && isActive) return
if (isAdmin) return
return
}
tsx
export default function Dashboard({ user, posts }: Props) {
const [filter, setFilter] = useState("all")
Mini Refactoring: From Spaghetti to Clean
const filteredPosts = posts.filter(p =>
filter === "all" ? true : p.type === filter
)
<select onChange={e => setFilter(e.target.value)}>
All
Tech
❌ Before
{filteredPosts.length === 0 ? (
No posts
) : (
filteredPosts.map(p =>
{p.title}
)
)}
)
}
tsx
function useFilteredPosts(posts: Post[]) {
const [filter, setFilter] = useState("all")
Step 1: isolate the logic
const filtered = posts.filter(post =>
filter === "all" ? true : post.type === filter
)
tsx
function PostFilter({ value, onChange }: Props) {
return (
<select value={value} onChange={e => onChange(e.target.value)}>
All
Tech
)
}
tsx
export default function Dashboard({ user, posts }: Props) {
const { filter, setFilter, filtered } = useFilteredPosts(posts)
{filtered.length === 0 ? (
No posts
) : (
filtered.map(p =>
{p.title}
)
)}
)
}
Step 3: compose everything
Refactoring works best when it’s part of your workflow, not something you postpone.
But if you ignore it, it slowly turns your codebase into something you avoid instead of something you trust.
Practical Refactoring Rituals
Final Thoughts
Orijinal makaleyi oku →
Bu içerik otomatik olarak derlenmektedir. Tüm haklar orijinal yayıncıya aittir.