<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ozan Ceylan</title>
    <description>The latest articles on DEV Community by Ozan Ceylan (@obceylan).</description>
    <link>https://dev.to/obceylan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1821973%2F3a3b4fdc-4681-4bd4-841a-1710c80e5738.png</url>
      <title>DEV Community: Ozan Ceylan</title>
      <link>https://dev.to/obceylan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/obceylan"/>
    <language>en</language>
    <item>
      <title>React Code Smells: 5 Tiny Patterns That Blow Up Your App Later</title>
      <dc:creator>Ozan Ceylan</dc:creator>
      <pubDate>Wed, 06 Aug 2025 10:44:55 +0000</pubDate>
      <link>https://dev.to/obceylan/react-code-smells-5-tiny-patterns-that-blow-up-your-app-later-18d6</link>
      <guid>https://dev.to/obceylan/react-code-smells-5-tiny-patterns-that-blow-up-your-app-later-18d6</guid>
      <description>&lt;p&gt;It always starts the same way.&lt;/p&gt;

&lt;p&gt;You’re building a component. It’s a small feature. Maybe a modal, a form, a list. You write it fast, ship it faster. Everything works. You move on.&lt;/p&gt;

&lt;p&gt;A few weeks later, you’re back.&lt;br&gt;&lt;br&gt;
Nothing’s technically “broken,” but something feels… off.&lt;/p&gt;

&lt;p&gt;The logic is tangled. The UI is buggy in weird ways.&lt;br&gt;&lt;br&gt;
You try to refactor it and realize: &lt;em&gt;“What the hell was I thinking?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Congratulations. You’ve just met a &lt;strong&gt;frontend smell&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Wait! What’s a “smell”?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A smell is not a bug. It’s worse.&lt;br&gt;&lt;br&gt;
It’s a &lt;strong&gt;tiny design flaw&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;feels harmless at first,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;slowly spreads,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and eventually makes your codebase hard to maintain, scale, or even read.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frontend smells aren’t always obvious. They hide inside reusable components, inline styles, overused state, and clever-looking hacks that come back to bite you.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Who is this for?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This post is for frontend developers who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;build fast,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;care about clean code (but don’t always have the time),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and want to avoid long-term pain.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’ve ever said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“I’ll clean this up later.”&lt;br&gt;&lt;br&gt;
or&lt;br&gt;&lt;br&gt;
“It’s just one component, no big deal.”&lt;br&gt;&lt;br&gt;
This post is especially for you.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;TL;DR&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Your frontend code may start clean, but small bad habits quickly snowball into big problems. This post covers 5 common frontend code smells — from inline functions and overused global state to magic strings — explaining why they cause trouble and how to replace them with cleaner, more maintainable patterns. If you’re a fast-moving junior dev or anyone who cares about code quality, this guide will help you avoid future headaches and write smarter code today.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Let’s talk about 5 innocent-looking patterns&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Each of these smells is small.&lt;br&gt;&lt;br&gt;
They’re not dramatic. They won’t throw errors.&lt;br&gt;&lt;br&gt;
But if you don’t catch them early, they’ll rot your code from the inside out.&lt;/p&gt;

&lt;p&gt;Let’s start with one of the most common culprits:&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Smell #1 — Anonymous Functions Everywhere&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Inline everything. What could possibly go wrong?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Smell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Inline arrow functions inside JSX are incredibly common:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks clean. One-liner. Easy to write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But here’s the catch&lt;/strong&gt;: every time your component re-renders, that function is re-created from scratch. And if you’re passing it to child components, they also re-render — even if nothing else changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why It’s a Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Breaks memoization&lt;/strong&gt; — Tools like &lt;code&gt;React.memo&lt;/code&gt;, &lt;code&gt;useMemo&lt;/code&gt;, and &lt;code&gt;useCallback&lt;/code&gt; become ineffective because the reference keeps changing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Causes unnecessary re-renders&lt;/strong&gt; — Especially dangerous in large lists or deeply nested UIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hides logic&lt;/strong&gt; — JSX becomes cluttered with logic that should live elsewhere.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Bad Example — Inline Handler in a List&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Show&lt;/span&gt; &lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything works… until your list gets longer, or you wrap &lt;code&gt;UserListItem&lt;/code&gt; in &lt;code&gt;React.memo&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Now every list item &lt;strong&gt;re-renders unnecessarily&lt;/strong&gt; — because that inline &lt;code&gt;onClick&lt;/code&gt; is always a &lt;strong&gt;new function&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Better Example — Extract the Handler&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleShowName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;handleShowName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Show&lt;/span&gt; &lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This small change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Makes your handler function &lt;strong&gt;stable&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enables &lt;strong&gt;React.memo&lt;/strong&gt; to do its job&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keeps JSX &lt;strong&gt;clean and focused on structure&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Bonus: useCallback When Needed&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If &lt;code&gt;handleShowName&lt;/code&gt; itself is passed down as a prop or used across renders, wrap it with &lt;code&gt;useCallback&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleShowName = useCallback((name) =&amp;gt; () =&amp;gt; {
  alert(name);
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That ensures the function reference &lt;strong&gt;doesn’t change between renders&lt;/strong&gt;, which is especially helpful in complex UIs or performance-critical components.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Inline functions feel fast and simple — but they silently ruin performance and scalability.&lt;br&gt;&lt;br&gt;
Get into the habit of &lt;strong&gt;lifting logic out of JSX&lt;/strong&gt; early. Your future self (and your teammates) will thank you.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Smell #2 — The Reusable-But-Not-Really Component&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“It’s reusable… if you don’t mind 12 props and 8 conditional classNames.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Smell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You build a component with reuse in mind. Let’s say a &lt;code&gt;Button&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
It starts simple. Then someone asks for a new color. Then a size. Then loading state.&lt;br&gt;&lt;br&gt;
Before you know it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
  &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt;
  &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"small"&lt;/span&gt;
  &lt;span class="na"&gt;isLoading&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"download"&lt;/span&gt;
  &lt;span class="na"&gt;fullWidth&lt;/span&gt;
  &lt;span class="na"&gt;align&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"left"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
  &lt;span class="na"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"none"&lt;/span&gt;
  &lt;span class="na"&gt;trackingId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cta_01"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you now have is a &lt;strong&gt;God Component in disguise&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Reusable? Technically.&lt;br&gt;&lt;br&gt;
Maintainable? Barely.&lt;br&gt;&lt;br&gt;
Debuggable? Good luck.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Why It’s a Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Too many props = complexity explosion&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You now need a spec sheet just to use the component.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Business logic starts leaking in&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Suddenly you’re handling “if icon exists and isLoading and type === ‘link’” inside a UI element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing becomes a nightmare&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Every edge case needs its own test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Bad Example — The “Universal” Button&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    btn 
    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn-primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn-sm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loading...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Icon&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt; : null&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On day 1, this looks smart.&lt;br&gt;&lt;br&gt;
On day 30, you’re writing conditionals that cancel each other out.&lt;br&gt;&lt;br&gt;
On day 90, no one wants to touch this button anymore.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Better — Split, Specialize, Compose&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Instead of one mega-component, split into smaller, focused components.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PrimaryButton.jsx&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use &lt;strong&gt;composition&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Icon&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"download"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  Download
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or expose &lt;strong&gt;slots&lt;/strong&gt; and &lt;strong&gt;variants intentionally&lt;/strong&gt; with well-defined contracts.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If a component has too many props, it’s trying to do too much.&lt;br&gt;&lt;br&gt;
A reusable component is only good &lt;strong&gt;if it’s predictable&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don’t build for “maybe we’ll need this someday.”&lt;br&gt;&lt;br&gt;
Build for “we need this now — and it’s easy to extend if we must.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Smell #3 — Magic Numbers &amp;amp; Strings&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why is ‘admin’ hardcoded in 6 different places? Who knows.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Smell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You’re deep in a feature, and you need to check the user role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// show secret stuff&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks harmless. Just a quick string.&lt;/p&gt;

&lt;p&gt;But then you see this again…&lt;br&gt;&lt;br&gt;
and again…&lt;br&gt;&lt;br&gt;
and again…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;read-only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your codebase is sprinkled with &lt;strong&gt;magic values&lt;/strong&gt; — strings and numbers with no context, no validation, and no shared meaning.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why It’s a Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hard to change&lt;/strong&gt; — Want to rename &lt;code&gt;'admin'&lt;/code&gt; to &lt;code&gt;'administrator'&lt;/code&gt;? Better hope you didn’t miss any.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No autocomplete or validation&lt;/strong&gt; — Typos like &lt;code&gt;'admn'&lt;/code&gt; won’t be caught until runtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Poor readability&lt;/strong&gt; — New developers have no idea what valid values are without hunting for them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Bad Example — Hardcoded Chaos&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getDashboardConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;canEdit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;canEdit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;canEdit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works — but it’s fragile.&lt;br&gt;&lt;br&gt;
One missed string and behavior breaks silently.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Better — Use Constants or Enums&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// roles.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;GUEST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./roles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getDashboardConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;canEdit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GUEST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;canEdit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;canEdit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;✅ Now your IDE helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Autocomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactoring&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type checking (if using TypeScript)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Bonus Tip: Enum + TypeScript = ❤️&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Guest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getDashboardConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// role must be one of the enum values&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This eliminates guesswork.&lt;br&gt;&lt;br&gt;
No more &lt;code&gt;"admin"&lt;/code&gt; strings flying around your app like uninvited guests.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If a value shows up more than once, give it a name.&lt;br&gt;&lt;br&gt;
Named constants beat mystery strings every time.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Magic numbers and strings might save you a few keystrokes now, but they’ll cost you hours during debugging and refactoring later.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Smell #4 — Overused Global State&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why is everything in context? This app has 4 pages.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Smell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You need to share a bit of state across components.&lt;br&gt;&lt;br&gt;
Naturally, you reach for Context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No problem so far.&lt;/p&gt;

&lt;p&gt;But next thing you know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The modal state is global&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current tab index is global&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That one-time toast message is global&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now your app has &lt;strong&gt;global everything&lt;/strong&gt;, and changing a button label causes half your app to re-render.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why It’s a Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unnecessary re-renders&lt;/strong&gt; — One state update can ripple through the entire app tree&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tight coupling&lt;/strong&gt; — Components far apart become silently dependent on shared state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hard to debug&lt;/strong&gt; — Where is this value updated? Why did it change? Who knows!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Bad Example — Global State for Local Concerns&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In Context&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isModalOpen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setModalOpen&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;isModalOpen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setModalOpen&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AppContext.Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then every component starts doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isModalOpen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setModalOpen&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the whole app re-renders every time the modal opens — even components that don’t care about modals at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Better — Localize What Can Be Local&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If the state is only relevant to a specific area — &lt;strong&gt;keep it there&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Page() {
  const [isModalOpen, setModalOpen] = useState(false);

  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setModalOpen(true)}&amp;gt;Open Modal&amp;lt;/button&amp;gt;
      {isModalOpen &amp;amp;&amp;amp; &amp;lt;Modal onClose={() =&amp;gt; setModalOpen(false)} /&amp;gt;}
    &amp;lt;/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even better? Use &lt;strong&gt;reducer hooks&lt;/strong&gt; or &lt;strong&gt;state machines&lt;/strong&gt; when things grow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Bonus Tip: Use Context Like a Scoped API, Not a Dumping Ground&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you must share state across unrelated components, &lt;strong&gt;create multiple small contexts&lt;/strong&gt;, not one mega-provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ModalProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ModalProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;UserProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each context only does &lt;strong&gt;one thing&lt;/strong&gt;, and you avoid unnecessary coupling.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Not all state is app-wide state.&lt;br&gt;&lt;br&gt;
Just because Context exists doesn’t mean you should use it for everything.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use local state by default. Reach for context &lt;strong&gt;only&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Props drilling is deep and unmanageable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The state is truly global (e.g., auth, theme)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance is under control (or you know how to memoize properly)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Smell #5 — Clever Code That Lies To You&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Nice one-liner bro… but what does it do again?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Smell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At some point, we all fall into this trap:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Look at this — destructuring, ternary, optional chaining,&lt;/em&gt; &lt;code&gt;reduce&lt;/code&gt;&lt;em&gt;, all in one neat line. So clean!”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And sure, it &lt;em&gt;feels&lt;/em&gt; clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But come back to this in two weeks and you’ll be like:&lt;/p&gt;

&lt;p&gt;🧠❌ “Wait, what does this actually do again?”&lt;br&gt;&lt;br&gt;
🫠📉 “Okay… so maybe it’s filtering… and multiplying… or something?”&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Why It’s a Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It’s hard to read&lt;/strong&gt; — Clever ≠ clear.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It’s hard to debug&lt;/strong&gt; — You can’t easily log or inspect the middle of a one-liner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It’s hard to change&lt;/strong&gt; — Refactoring gets risky when logic is condensed into a dense syntax salad.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It confuses others (and future you)&lt;/strong&gt; — Your teammate (or yourself, 3 months later) won’t thank you.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Bad Example — Ternaryception&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🟢 Active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🟡 Pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🔴 Inactive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Yes, it technically works.&lt;br&gt;&lt;br&gt;
But it reads like you’re trying to write JavaScript poetry.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Better — Be Explicit, Be Kind&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStatusLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🟢 Active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🟡 Pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🔴 Inactive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now it’s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Easy to follow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy to extend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy to test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No brain gymnastics required.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Bonus Tip: Split, Name, and Simplify&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If your logic is slightly complex — &lt;strong&gt;split it into steps&lt;/strong&gt; and &lt;strong&gt;name things&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;positiveNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doubled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;positiveNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, annotate your chains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Filter out invalid users and sort by last login&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastLogin&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastLogin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s still clean. But now it &lt;strong&gt;communicates intention&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If a line of code needs a Slack thread to explain it…&lt;br&gt;&lt;br&gt;
You probably shouldn’t write it that way.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Readable code is kind code&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Cleverness might impress &lt;em&gt;you&lt;/em&gt; — but clarity helps &lt;em&gt;everyone&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion: Small Smells, Big Headaches&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Code doesn’t rot overnight.&lt;br&gt;&lt;br&gt;
It happens slowly — with innocent shortcuts, rushed decisions, and “I’ll clean this up later” promises.&lt;/p&gt;

&lt;p&gt;Each of the five patterns we covered might seem harmless at first. But left unchecked, they snowball into bugs, confusion, and refactoring pain. The good news? Most of these are &lt;strong&gt;easy to avoid with a little awareness&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So next time you’re in the zone, ask yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Is this clever… or is this clear?”&lt;br&gt;&lt;br&gt;
“Is this temporary… or is this maintainable?”&lt;br&gt;&lt;br&gt;
“Am I writing for the computer… or for the next developer?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer makes you squint — it’s probably a smell.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Smell Checklist — Watch Out for These&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. 🚫 Anonymous Functions Everywhere&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Don’t&lt;/strong&gt;: Write inline functions like &lt;code&gt;onClick={() =&amp;gt; doSomething()}&lt;/code&gt; in every JSX element&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Do&lt;/strong&gt;: Extract named functions and reuse them for cleaner, more testable code&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 🚫 Copy-Paste Components&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Don’t&lt;/strong&gt;: Duplicate components with slightly different props or layouts&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Do&lt;/strong&gt;: Create base/shared components with flexible props or composition&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. 🚫 Magic Numbers &amp;amp; Strings&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Don’t&lt;/strong&gt;: Hardcode values like &lt;code&gt;'admin'&lt;/code&gt;, &lt;code&gt;'blue'&lt;/code&gt;, &lt;code&gt;42&lt;/code&gt; throughout your app&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Do&lt;/strong&gt;: Define constants, enums, or config objects for consistency and readability&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. 🚫 Overused Global State&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Don’t&lt;/strong&gt;: Store everything in Context or Redux just because you &lt;em&gt;might&lt;/em&gt; reuse it&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Do&lt;/strong&gt;: Keep state local unless it’s truly shared across distant parts of the app&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. 🚫 Clever Code That Lies to You&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Don’t&lt;/strong&gt;: Write dense one-liners just to be fancy&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Do&lt;/strong&gt;: Split logic into readable steps, name things clearly, and leave breadcrumbs for future-you&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;👣 Final Thought&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Frontend development is fast-paced. But “fast” doesn’t have to mean “fragile”.&lt;/p&gt;

&lt;p&gt;When you catch these smells early, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Help your teammates move faster&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make debugging 10× easier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save your &lt;em&gt;future self&lt;/em&gt; a lot of headaches&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Good code isn’t just about making it work — it’s about making it last.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Common MVP UX Mistakes That Make Users Quit, and How to Avoid Them</title>
      <dc:creator>Ozan Ceylan</dc:creator>
      <pubDate>Tue, 05 Aug 2025 09:49:36 +0000</pubDate>
      <link>https://dev.to/obceylan/common-mvp-ux-mistakes-that-make-users-quit-and-how-to-avoid-them-3e6m</link>
      <guid>https://dev.to/obceylan/common-mvp-ux-mistakes-that-make-users-quit-and-how-to-avoid-them-3e6m</guid>
      <description>&lt;p&gt;You’ve poured countless hours into coding your Minimum Viable Product. You crafted outreach campaigns, ran online ads, and finally, after all that hustle, real users got a chance to try your product. You were excited, ready to see the feedback roll in.&lt;/p&gt;

&lt;p&gt;But then reality hit: users struggled. They clicked around confused, abandoned key flows, or bounced faster than you expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvnkph44ek23feoqgju6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvnkph44ek23feoqgju6.png" alt="Confused" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the hard truth: your MVP might look fine, but it hurts to use.&lt;/p&gt;

&lt;p&gt;Many technical founders and indie devs fall into the same trap: obsessing over whether the product technically works, but forgetting about how frustrating it is to actually use. And that frustration? It kills momentum before you even get started.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore the most common UX mistakes in early MVPs and how to avoid them. Because building something that works isn’t enough. You need to build something people want to keep using.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5 Most Common UX Mistakes in Early MVPs
&lt;/h2&gt;

&lt;p&gt;When you’re building an MVP, it’s easy to fall into traps that slow down or outright lose your users. Here are the top five UX mistakes that indie devs and technical founders often make — and why they hurt your product’s chances.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assuming “Users Will Just Figure It Out”
&lt;/h3&gt;

&lt;p&gt;You’ve been living in your product’s world for weeks. You know every button, every flow, every detail. So it feels natural to think users will “just figure it out.”&lt;/p&gt;

&lt;p&gt;But they won’t. If your product isn’t instantly clear, users get frustrated and leave fast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclpqnwlq7gjou93zbx62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclpqnwlq7gjou93zbx62.png" alt="Not Clear" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix it:&lt;/strong&gt;&lt;br&gt;
Test your MVP with someone who matches your target user profile, someone who’s likely to actually use your product. Watch where they hesitate or get stuck. Simplify your UI and add clear labels or hints. Remember, clarity beats cleverness every time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Broken Flows and Confusing Navigation
&lt;/h3&gt;

&lt;p&gt;Your MVP might technically work, but if users get lost or stuck trying to move between screens, it’s a no-go. Confusing navigation or dead ends make users frustrated and erode trust quickly.&lt;/p&gt;

&lt;p&gt;Often, these dead ends happen because of links or buttons leading to features not yet available, like “coming soon” pages or unfinished sections. While it’s tempting to showcase your product vision, these placeholders can confuse users more than help them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx41lxpy13wlb43dxd7x5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx41lxpy13wlb43dxd7x5.png" alt="Dead End" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix it:&lt;/strong&gt;&lt;br&gt;
Map out your user flow before coding. Test the entire journey with real users who fit your target audience. Make sure each step naturally leads to the next. If a feature isn’t ready, hide or disable its link to avoid confusion. Simplify menus, add clear buttons like “Next” or “Back,” and avoid surprises.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI Without UX: Looks Don’t Guarantee Usability
&lt;/h3&gt;

&lt;p&gt;Your MVP might have a clean, minimal design with buttons and elements perfectly aligned. But if users don’t understand why those buttons are there or what they do, your UI is just decoration, not a tool.&lt;/p&gt;

&lt;p&gt;Minimalism is great, but too much “empty space” without guidance can make users feel lost or abandoned. Lack of tooltips, onboarding hints, or clear microcopy leaves users guessing what to do next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbc7vblrv9qdandrhvxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbc7vblrv9qdandrhvxt.png" alt="On Board" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix it:&lt;/strong&gt;&lt;br&gt;
Add simple onboarding steps or tooltips that guide first-time users through key actions. Use clear and descriptive labels on buttons and links. Think of your UI as a conversation with your user, make sure it talks back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Silent Forms and Meaningless Errors
&lt;/h3&gt;

&lt;p&gt;Users often spend time filling out long forms only to find out they can’t submit, and worse, they have no idea why. This confusion quickly turns into frustration and abandonment.&lt;/p&gt;

&lt;p&gt;Long forms without proper validation or clear error messages kill user motivation. Keeping forms short and implementing precise validations with actionable feedback is critical to keep users moving forward.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgjhk5qohii4dcsjls28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgjhk5qohii4dcsjls28.png" alt="Error Oops" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix it:&lt;/strong&gt;&lt;br&gt;
Break long forms into smaller, manageable steps. Use real-time validation and clear, specific error messages. For example, instead of a vague “Invalid input,” say “Password must be at least 8 characters.” Help users understand exactly what went wrong and how to fix it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing for Yourself, Not Your Users
&lt;/h3&gt;

&lt;p&gt;It’s easy to build the product you would use or understand best. But your users are not you, they have different needs, skills, and expectations.&lt;/p&gt;

&lt;p&gt;When you design for yourself, you risk creating confusing flows, missing onboarding, or adding features that don’t solve real problems. This empathy gap can make your MVP frustrating or irrelevant to your target audience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mnpn8gynpepaehd8ahh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mnpn8gynpepaehd8ahh.png" alt="User group" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix it:&lt;/strong&gt;&lt;br&gt;
Get out of your own head and into your users’ shoes. Conduct user interviews, gather feedback from real prospects, and watch how they interact with your MVP. Design with empathy, it’s the key to building something people actually want to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Your MVP’s UX Is Its Heartbeat
&lt;/h2&gt;

&lt;p&gt;Building an MVP is about more than just showing which problem you’re solving for your users, it’s also about how easily and smoothly you solve it. If your MVP makes users jump through hoops or leaves them confused, they won’t stick around long enough to appreciate the value you offer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt;&lt;br&gt;
Solving a problem is important, but solving it effortlessly is what keeps users coming back.&lt;/p&gt;

&lt;p&gt;Invest time early on in simple UX fixes, empathize with your users, and keep testing. The smoother and clearer your MVP feels, the more users will stay engaged, and that’s the real minimum viable success.&lt;/p&gt;

&lt;p&gt;Keep building boldly, but build kindly too.&lt;/p&gt;

</description>
      <category>mvp</category>
      <category>ux</category>
      <category>churn</category>
      <category>pitfalls</category>
    </item>
  </channel>
</rss>
