<?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>Forem: Fulya Cimendere</title>
    <description>The latest articles on Forem by Fulya Cimendere (@fcimendere).</description>
    <link>https://forem.com/fcimendere</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%2F2436647%2F97d91451-3558-47fe-b630-bf4f2e4ff194.jpg</url>
      <title>Forem: Fulya Cimendere</title>
      <link>https://forem.com/fcimendere</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fcimendere"/>
    <language>en</language>
    <item>
      <title>From Interview Failure to "Aha!" Moment: How a Screaming Terminal Taught Me Debouncing</title>
      <dc:creator>Fulya Cimendere</dc:creator>
      <pubDate>Fri, 26 Dec 2025 08:39:37 +0000</pubDate>
      <link>https://forem.com/fcimendere/from-interview-failure-to-aha-moment-how-a-screaming-terminal-taught-me-debouncing-49b6</link>
      <guid>https://forem.com/fcimendere/from-interview-failure-to-aha-moment-how-a-screaming-terminal-taught-me-debouncing-49b6</guid>
      <description>&lt;p&gt;During a technical interview once, I was asked: "What is debouncing, how do you use it, and why?" I blanked. I gave a generic answer, but I didn't really get it. Even after researching it later, the concept felt like abstract theory—until my terminal started screaming at me.&lt;/p&gt;

&lt;p&gt;While developing a React Native app for asylum seekers in the Netherlands, I hit a wall. My Supabase logs were exploding with errors, and users were getting "bounced" out of the group creation flow. That’s when the theory became a reality.&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%2Fi1td09smk5lm1sk6pp99.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%2Fi1td09smk5lm1sk6pp99.png" alt=" " width="800" height="1739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture this: You're building a beautiful React Native app. Everything is going smoothly until you test the Group Creation progress. Every time you try, you have met with cryptic error messages and endless retry loops. Sound familiar?&lt;/p&gt;

&lt;p&gt;This is the story of how a seemingly simple feature turned into a debugging nightmare, and how understanding &lt;strong&gt;debouncing&lt;/strong&gt; saved our app from user abandonment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: The "Bouncing" Disaster
&lt;/h2&gt;

&lt;p&gt;It was a day when I received many unnecessary error logs - that was looking like, during the input of description, there were many unnecessary LOGs, which looked like every letter made another API call!&lt;/p&gt;

&lt;p&gt;We were literally "bouncing" between the group creation form and error messages, unable to complete what should have been a straightforward task.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Error That Haunted Our Dreams
&lt;/h3&gt;

&lt;p&gt;Here's what users were seeing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Console Error - Log 1 of 1

Error adding creator as member:
{"code":"23505","details":null,"hint":null,
"message":"duplicate key value violates unique constraint 
\"group_members_group_id_user_id_key\""}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Translation&lt;/strong&gt;: Our database was screaming, "Hey, you're trying to add the same person to the same group twice!"&lt;/p&gt;

&lt;p&gt;But here's the kicker — users were only clicking the "Create Group" button once. So why was our database throwing a tantrum?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Debouncing? (And When You Actually Need It)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Debouncing&lt;/strong&gt; is a technique that prevents a function from being called too frequently by waiting for a pause in activity before executing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Elevator Analogy
&lt;/h3&gt;

&lt;p&gt;Imagine you're in an elevator, and someone keeps pressing the "Close Door" button rapidly. Without debouncing, the elevator would try to close the door for every single press — creating a mechanical nightmare.&lt;/p&gt;

&lt;p&gt;With debouncing, the elevator says: "I'll wait until you stop pressing the button for 2 seconds, then I'll close the door once."&lt;/p&gt;

&lt;h3&gt;
  
  
  In Programming Terms
&lt;/h3&gt;

&lt;p&gt;Debouncing delays function execution until after a specified time has passed since the last time it was invoked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key principle&lt;/strong&gt;: "Wait for the user to stop, then act once."&lt;/p&gt;

&lt;h2&gt;
  
  
  Debouncing vs Throttling: Know the Difference
&lt;/h2&gt;

&lt;p&gt;Since these terms are often confused, let's clarify:&lt;/p&gt;

&lt;h3&gt;
  
  
  Debouncing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When&lt;/strong&gt;: Execute function AFTER user stops the action&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for&lt;/strong&gt;: Search input, button clicks, form validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: "Wait 500ms after user stops typing, then search"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Throttling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When&lt;/strong&gt;: Execute function at REGULAR INTERVALS during the action
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for&lt;/strong&gt;: Scroll events, mouse movements, resize events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: "Update scroll position every 100ms while scrolling"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our group creation problem, we needed &lt;strong&gt;debouncing&lt;/strong&gt; because we wanted to wait for user actions to complete before executing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Don't use debouncing for everything! It's specifically for scenarios where you want to wait for user activity to pause.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three-Headed Monster: Our Debouncing Problems
&lt;/h2&gt;

&lt;p&gt;Our group creation feature had not one, but &lt;strong&gt;three&lt;/strong&gt; debouncing issues:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Database Constraint Violation
&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;//  PROBLEMATIC CODE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memberError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;group_members&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="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;group_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newGroup&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="na"&gt;user_id&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;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="na"&gt;role&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;notifications_enabled&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;memberError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This would crash the entire group creation&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to add creator as member&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;&lt;strong&gt;What went wrong&lt;/strong&gt;: If a user clicked "Create Group" twice (even accidentally), the second click would try to insert the same membership record again, violating our database's unique constraint.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Keystroke API Avalanche
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;: Every time users typed in the group description field, we were making API calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//  PROBLEMATIC CODE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDescriptionChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;setDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// This fires on EVERY keystroke!&lt;/span&gt;
  &lt;span class="nf"&gt;validateGroupDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;saveGroupDraft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&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;&lt;strong&gt;What went wrong&lt;/strong&gt;: Typing "Hello World" would trigger 11 API calls. Users experienced laggy input fields and our server was getting hammered.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Button Mashing Mayhem
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;: No protection against rapid button clicks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ PROBLEMATIC CODE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleCreateGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="c1"&gt;// No protection against multiple clicks&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;GroupService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;groupData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;Alert&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success&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;Group created!&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;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Alert&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;&lt;strong&gt;What went wrong&lt;/strong&gt;: Impatient users would tap "Create Group" multiple times, creating race conditions and duplicate operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Great Debugging Adventure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Following the Breadcrumbs
&lt;/h3&gt;

&lt;p&gt;The error message was our first clue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error Code 23505&lt;/strong&gt;: PostgreSQL unique constraint violation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraint&lt;/strong&gt;: &lt;code&gt;group_members_group_id_user_id_key&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location&lt;/strong&gt;: Line 81 in our group service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This told us that we were trying to create duplicate group memberships.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: The "Aha!" Moment
&lt;/h3&gt;

&lt;p&gt;We realized that our group creation was actually &lt;strong&gt;partially succeeding&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ Group gets created in database&lt;/li&gt;
&lt;li&gt;❌ Adding creator as member fails (duplicate constraint)&lt;/li&gt;
&lt;li&gt;😡 User sees error and tries again&lt;/li&gt;
&lt;li&gt;🔄 Repeat cycle of frustration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The group existed, but the user couldn't access it because they weren't properly added as a member.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: A Three-Pronged Attack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fix #1: Database Upsert Magic
&lt;/h3&gt;

&lt;p&gt;We replaced &lt;code&gt;INSERT&lt;/code&gt; with &lt;code&gt;UPSERT&lt;/code&gt; operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ FIXED CODE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memberError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;group_members&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="nf"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;group_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newGroup&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="na"&gt;user_id&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;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="na"&gt;role&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;notifications_enabled&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onConflict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;group_id,user_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;  &lt;span class="c1"&gt;// Handle duplicates gracefully&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;memberError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error adding creator as member:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;memberError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Don't fail the entire group creation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: If a user is already a member, update their record. If not, create a new one. No more constraint violations!&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix #2: Input Debouncing Elegance
&lt;/h3&gt;

&lt;p&gt;We implemented proper input debouncing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ FIXED CODE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useDebounceInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&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;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&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="nx"&gt;initialValue&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;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDebouncedValue&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="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&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;setDebouncedValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;delay&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;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;debouncedValue&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Usage in component&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;setDescription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;debouncedValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="nf"&gt;useDebounceInput&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="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Only trigger API calls when user stops typing for 500ms&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="nf"&gt;validateGroupDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;debouncedValue&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="nx"&gt;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: API calls only fire 500ms after the user stops typing. Typing "Hello World" now triggers just 1 API call instead of 11!&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix #3: Button State Management
&lt;/h3&gt;

&lt;p&gt;We added proper loading states and button debouncing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ FIXED CODE&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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleCreateGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;if &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="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Prevent multiple calls&lt;/span&gt;

  &lt;span class="nf"&gt;setIsLoading&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="k"&gt;try&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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;GroupService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;groupData&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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Alert&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;Alert&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success&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;Group created!&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;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoading&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// In the render&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TouchableOpacity&lt;/span&gt;
  &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleCreateGroup&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&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="c1"&gt;// Disable during operation&lt;/span&gt;
  &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buttonDisabled&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ActivityIndicator&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="s2"&gt;small&lt;/span&gt;&lt;span class="dl"&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="p"&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;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Create&lt;/span&gt; &lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;/TouchableOpacity&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Button becomes disabled during group creation, preventing multiple simultaneous requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results: From Chaos to Harmony
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before the Fix:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; 73% of group creation attempts failed&lt;/li&gt;
&lt;li&gt; Users reported laggy input fields&lt;/li&gt;
&lt;li&gt; Support tickets flooding in daily&lt;/li&gt;
&lt;li&gt; Database filled with orphaned groups&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  After the Fix:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; 99.2% group creation success rate&lt;/li&gt;
&lt;li&gt; Smooth, responsive input fields&lt;/li&gt;
&lt;li&gt; Zero constraint violation errors&lt;/li&gt;
&lt;li&gt; Happy users creating communities&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Should You Actually Use Debouncing?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Be careful!&lt;/strong&gt; Debouncing isn't a silver bullet. Use it only when you specifically need to wait for user activity to pause.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good Debouncing Scenarios:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Search Input Fields
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt;: Users type multiple characters quickly, you want to search their complete term&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: Search after user stops typing for 300ms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't use for&lt;/strong&gt;: Instant character by character filtering (use direct state updates)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Expensive Operations
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API calls&lt;/strong&gt;: Prevent multiple requests while user is still inputting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database writes&lt;/strong&gt;: Wait for user to finish editing before saving&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File uploads&lt;/strong&gt;: Prevent accidental multiple uploads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment processing&lt;/strong&gt;: Critical to prevent double charges&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Form Validation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt;: Don't show errors while user is actively typing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: Validate email format after user stops typing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't use for&lt;/strong&gt;: Simple client-side checks that should be immediate&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. Button Spam Prevention
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt;: Prevent accidental double-clicks on important actions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: Disable submit button during processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't use for&lt;/strong&gt;: Navigation buttons or simple UI interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Don't Use Debouncing For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Immediate UI feedback&lt;/strong&gt; (button hover states, focus changes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time features&lt;/strong&gt; (live chat, collaborative editing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Navigation actions&lt;/strong&gt; (menu clicks, page transitions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple state updates&lt;/strong&gt; (toggling switches, selecting options)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scroll-based features&lt;/strong&gt; (use throttling instead)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ask Yourself:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do I want this to happen while the user is actively doing something?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If YES → Don't use debouncing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Is this an expensive operation that I want to delay?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If YES → Consider debouncing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Will delaying this action improve user experience?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If NO → Don't use debouncing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Debouncing Patterns That Saved Us
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pattern 1: Classic Debounce Function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;debounce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;let&lt;/span&gt; &lt;span class="na"&gt;timeoutId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Timeout&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;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeoutId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;timeoutId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&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;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;delay&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="c1"&gt;// Usage examples from our fixes&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;debouncedSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// Search input&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;debouncedSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saveFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// Auto-save&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;debouncedValidate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validateForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// Form validation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern 2: React Hook Debouncing (Our Text Input Fix)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useDebounce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDebouncedValue&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&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;setDebouncedValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;delay&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;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Usage in our group description field&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDebounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern 3: State-Based Debouncing (Our Button Fix)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;isProcessing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsProcessing&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;debouncedAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isProcessing&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="c1"&gt;// Prevent multiple calls&lt;/span&gt;

  &lt;span class="nf"&gt;setIsProcessing&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;performAction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsProcessing&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern 4: Custom Debounce Hook (Advanced)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useDebounceCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;debounceTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDebounceTimer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Timeout&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="nx"&gt;debouncedCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;((...&lt;/span&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;debounceTimer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;debounceTimer&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;newTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&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;callback&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;setDebounceTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTimer&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="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;debounceTimer&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;debouncedCallback&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;h2&gt;
  
  
  Lessons Learned: The Wisdom of Hindsight
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Always Expect the Unexpected
&lt;/h3&gt;

&lt;p&gt;Users will click buttons multiple times, type rapidly, and do things you never anticipated. Plan for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Database Constraints Are Your Friends
&lt;/h3&gt;

&lt;p&gt;That "annoying" unique constraint actually prevented data corruption. Embrace constraints, but handle violations gracefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. User Experience Trumps Technical Perfection
&lt;/h3&gt;

&lt;p&gt;A slightly delayed API call is infinitely better than a broken feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Test with Real User Behavior
&lt;/h3&gt;

&lt;p&gt;Automated tests are great, but nothing beats testing with actual users who click buttons like their life depends on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway: Debouncing as a Mindset
&lt;/h2&gt;

&lt;p&gt;Debouncing isn't just a technical solution — it's a mindset. It's about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Anticipating user behavior&lt;/strong&gt; instead of reacting to it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building resilient systems&lt;/strong&gt; that handle edge cases gracefully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prioritizing user experience&lt;/strong&gt; over technical convenience&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thinking in terms of user flows&lt;/strong&gt; rather than individual functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your Turn: The Debouncing Decision Framework
&lt;/h2&gt;

&lt;p&gt;Before implementing debouncing, use this decision framework:&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 The Three Question Test:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Is this operation expensive or irreversible?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls, database writes, payments → Consider debouncing&lt;/li&gt;
&lt;li&gt;UI updates, state changes → Probably don't need debouncing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Do I want to wait for the user's "final" input?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search queries, form validation → Yes, use debouncing&lt;/li&gt;
&lt;li&gt;Button clicks, navigation → No, act immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Will a delay improve the user experience?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducing API spam → Yes, debouncing helps&lt;/li&gt;
&lt;li&gt;Providing instant feedback → No, debouncing hurts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  📋 Quick Reference:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ USE DEBOUNCING FOR:
- Search input (300-500ms)
- Form validation (500ms)
- Auto-save (1000ms)
- API calls (prevent spam)
- Expensive operations

❌ DON'T USE DEBOUNCING FOR:
- Button hover effects
- Navigation clicks
- Simple state updates
- Real-time features
- Immediate UI feedback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pro Tips:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start without debouncing&lt;/strong&gt; - add it only when you have a specific problem&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test with real users&lt;/strong&gt; - they'll reveal if your delays feel natural&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep delays short&lt;/strong&gt; - 300-500ms is usually enough&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provide visual feedback&lt;/strong&gt; - users should know something is happening&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consider the context&lt;/strong&gt; - search can wait, emergency buttons cannot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: Debouncing is a tool for specific problems, not a general solution for all user interactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: From Bouncing to Smooth Sailing
&lt;/h2&gt;

&lt;p&gt;What started as a frustrating bug report turned into a valuable lesson about the importance of debouncing in modern app development. By understanding user behavior, implementing proper state management, and using database operations wisely, we transformed a broken feature into a smooth, reliable experience.&lt;/p&gt;

&lt;p&gt;Our users went from bouncing between error messages to successfully creating the communities they needed. And isn't that what great software development is all about?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you encountered similar debouncing challenges in your projects? Share your experiences in the comments below! And if this article helped you solve a tricky bug, give it a clap 👏&lt;/em&gt;&lt;/p&gt;

</description>
      <category>debouncing</category>
      <category>frontend</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>Creating an Interactive Navigation Circle with React</title>
      <dc:creator>Fulya Cimendere</dc:creator>
      <pubDate>Fri, 21 Feb 2025 08:56:38 +0000</pubDate>
      <link>https://forem.com/fcimendere/creating-an-interactive-navigation-circle-with-react-5feb</link>
      <guid>https://forem.com/fcimendere/creating-an-interactive-navigation-circle-with-react-5feb</guid>
      <description>&lt;h2&gt;
  
  
  A Deep Dive into Scroll-Based Animations
&lt;/h2&gt;

&lt;p&gt;Have you ever wanted to create a unique navigation experience that combines smooth scrolling with visual feedback? In this article, I'll walk you through how I implemented an interactive navigation system featuring a rotating clock animation that responds to both button clicks and scroll positions.&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%2Fhy8w5ba5fg0l60jjwwzs.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%2Fhy8w5ba5fg0l60jjwwzs.png" alt="Magic Circle View" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Navigation System: More Than Just Buttons
&lt;/h2&gt;

&lt;p&gt;The navigation system consists of two main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A set of gradient buttons for different sections ("About", "Project", "Experience", "Contact") - for more about gradient buttons visit &lt;strong&gt;&lt;a href="https://www.reactbits.dev/" rel="noopener noreferrer"&gt;reactbits&lt;/a&gt; &lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;circular clock-like indicator&lt;/strong&gt; that rotates to point at the currently active section.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Navigation Implementation
&lt;/h2&gt;

&lt;p&gt;The navigation buttons are implemented using a combination of React components and the &lt;code&gt;react-scroll&lt;/code&gt; library. Here's the key part from the &lt;code&gt;Home&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{["about", "project", "experience", "contact"].map((section) =&amp;gt; (
  &amp;lt;GradientTextButton key={section} aria-label={`Navigate to ${section}&amp;gt;
    &amp;lt;Link
      key={section}
      id={`link-${section}`}
      to={section}
      smooth={true}
      duration={500}
      onClick={() =&amp;gt; handleClick(`link-${section}`)}
      tabIndex={0}
      onKeyDown={(e) =&amp;gt; {
        if (e.key === "Enter") handleClick(`link-${section}`);
      }}
    &amp;gt;
      &amp;lt;span className="dark:text-lighttext"&amp;gt;
        {section.charAt(0).toUpperCase() + section.slice(1)}
      &amp;lt;/span&amp;gt;
    &amp;lt;/Link&amp;gt;
  &amp;lt;/GradientTextButton&amp;gt;
))}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What makes this special?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The the the &lt;code&gt;smooth={true}&lt;/code&gt; property ensures smooth scrolling animation&lt;/li&gt;
&lt;li&gt;Each button triggers two actions:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Scrolls to the target section&lt;/li&gt;
&lt;li&gt;Updates the &lt;code&gt;activeId&lt;/code&gt; state which controls the circle rotati
on&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Magic Circle
&lt;/h2&gt;

&lt;p&gt;The circle indicator is where things get interesting. The &lt;code&gt;Circle.jsx&lt;/code&gt; component listens for changes to the &lt;code&gt;id&lt;/code&gt; prop (which represents the active section). Based on this prop, it adjusts the rotation of the inner circle to correspond to the section. This is done through simple CSS transforms, allowing the circle to rotate based on which section is active.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getRotation = (id) =&amp;gt; {
  switch (id) {
    case "link-about": return `rotate(145deg)`;
    case "link-project": return `rotate(170deg)`;
    case "link-experience": return `rotate(190deg)`;
    case "link-contact": return `rotate(215deg)`;
    default: return `rotate(0deg)`;
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The clever part:&lt;/strong&gt; The rotation values are carefully calibrated to point at each section's button position, creating a seamless connection between the indicator and navigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scroll-Based Updates
&lt;/h2&gt;

&lt;p&gt;The system doesn't just respond to clicks - it also updates based on scroll position using the Intersection Observer API. In &lt;code&gt;RightSection.jsx:&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 sections = ["about", "project", "experience", "contact"];
const activeSection = useIntersectionObserver(sections);

useEffect(() =&amp;gt; {
  if (activeSection) {
    onSectionChange(`link-${activeSection}`);
  }
}, [activeSection, onSectionChange]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; This creates a two-way connection where both scrolling and clicking update the navigation state, ensuring the UI always reflects the user's current position.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: What Could Be Better
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Progressive Animation:&lt;/strong&gt; 
Implement velocity-based animation for more natural movement &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Improvements: &lt;/strong&gt;
Implement virtual scrolling for longer content sections 
Optimize the Intersection Observer thresholds for smoother transitions 
3.** Accessibility Enhancements: **&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow me:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/fulya-cimendere/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/FCimendere" rel="noopener noreferrer"&gt;GitHub &lt;/a&gt;|  &lt;a href="//bit.ly/fcimendere"&gt;Portfolio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>ui</category>
    </item>
    <item>
      <title>You’ve Decided to Change Your Career, What’s Next?</title>
      <dc:creator>Fulya Cimendere</dc:creator>
      <pubDate>Tue, 24 Dec 2024 21:06:55 +0000</pubDate>
      <link>https://forem.com/fcimendere/youve-decided-to-change-your-career-whats-next-58cp</link>
      <guid>https://forem.com/fcimendere/youve-decided-to-change-your-career-whats-next-58cp</guid>
      <description>&lt;h2&gt;
  
  
  Simple Tips for Starting Your Career in Software Development
&lt;/h2&gt;

&lt;p&gt;Switching careers after a long time of experience in another industry and starting a new professional life is not easy, especially in competitive fields like software development. It requires not only technical skills but also a continuous learning mindset.&lt;/p&gt;

&lt;p&gt;In this article, I won’t tell you how to find a job or recommend technical resources. Instead, I’ll share my personal methods for starting and staying motivated as a new software developer. These methods focus on three key points: &lt;strong&gt;setting clear goals, staying motivated, and avoiding distractions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Set Clear Goals&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you decide to enter the world of software development, you’ve likely already done some research. Let’s face it: it can be overwhelming. Thousands of opinions, people claiming that &lt;em&gt;“this is the best programming language!”&lt;/em&gt; or advice like &lt;em&gt;“learn this new technology”&lt;/em&gt; can easily leave you confused.&lt;/p&gt;

&lt;p&gt;Don’t assume front-end development is the easiest path. Believe me, it is not! Instead, &lt;strong&gt;think about what excites you&lt;/strong&gt;. If finding mistakes or bugs sounds interesting, maybe testing is your thing.&lt;/p&gt;

&lt;p&gt;If you have no idea what interests you, don’t worry. There are thousands of articles and resources to help you explore options. Remember, not everyone needs to be a front-end developer.&lt;/p&gt;

&lt;p&gt;Once you’ve identified your interest, the next step is to follow a clear &lt;strong&gt;roadmap&lt;/strong&gt; for that area. Websites like &lt;a href="https://roadmap.sh/" rel="noopener noreferrer"&gt;roadmap.sh&lt;/a&gt; offer excellent guides. Having a structured plan will keep you focused and prevent you from getting lost in the vast ocean of possibilities. With each step you complete, your next move will become clear.&lt;/p&gt;

&lt;p&gt;After setting a plan, &lt;strong&gt;look for educational resources&lt;/strong&gt;. There are countless free resources available, so a bit of research can go a long way. To avoid burnout, &lt;strong&gt;create a personalized learning program based on your interests&lt;/strong&gt;. I plan to share a repository listing the resources I’ve found helpful in the future, but for now, start by building your own list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Stay Motivate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Having access to so many resources can sometimes feel like you’re stuck in an endless loop. Even well-meaning advice from experienced developers can confuse you. To stay on track, it’s crucial to maintain your motivation. Here are some methods that worked for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pomodoro Technique:&lt;/strong&gt; The Pomodoro Technique is a time management method where you work for 25 minutes and then take a 5-minute break. After four cycles, you take a longer 20–30 minute break. This method helps your brain stay refreshed while working.&lt;br&gt;
Free tools like &lt;a href="https://pomodoro-tracker.com/" rel="noopener noreferrer"&gt;Pomodoro Tracker&lt;/a&gt; allow you to track how much time you spend on different topics and even your total learning time over the year. For example, I spent 115 hours (167 Pomodoros) completing a Full-Stack Web Development Bootcamp, including exercises and projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Eat the Frog:&lt;/strong&gt; This productivity method involves tackling the hardest task first thing in the morning. If you have two challenging tasks, start with the more difficult one. This approach helps prevent procrastination caused by dread.&lt;br&gt;
For me, learning something new in the morning works best because my mind is fresh and free from distractions. This could be reading an article or taking detailed notes on a technical topic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;To-Do Lists:&lt;/strong&gt; A classic but effective method. Believe me, it works! When you have multiple tasks, tracking them individually simplifies the process. Crossing off completed tasks also activates a reward mechanism in your brain, giving you a sense of accomplishment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Avoid Distractions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Distractions, even those that seem harmless, can significantly derail your progress.&lt;/p&gt;

&lt;p&gt;As you dive deeper into learning and the difficulty level increases, staying consistent becomes harder. This can lead to lower self-esteem and push you towards what is called the &lt;em&gt;“giving up curve”&lt;/em&gt; or &lt;em&gt;“quitting point”&lt;/em&gt; — what is the hell this quitting point -&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%2F2piiv21pf5prnhp2b7ha.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%2F2piiv21pf5prnhp2b7ha.png" alt="The quitting point curve from Tomas Svitorka" width="800" height="520"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The quitting point curve from Tomas Svitorka&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Social media and platforms like Instagram, LinkedIn, X can seem harmless or even helpful. However, they often trigger feelings of competition or inadequacy. Limit your exposure to these platforms during your workday.&lt;/p&gt;

&lt;p&gt;Personally, I use &lt;strong&gt;“Do Not Disturb”&lt;/strong&gt; mode on my phone and keep it out of sight during work. You’d be surprised how much mental energy it takes just to resist checking your phone.&lt;/p&gt;

&lt;p&gt;Living away from my family, I also avoid phone calls during the day unless it’s an emergency. Emotional triggers can be hard to control and are among the most demotivating distractions.&lt;/p&gt;

&lt;p&gt;Additionally, I follow a daily wake-up routine with clear goals for the day. This helps me wake up with purpose and builds a long-term sense of self-appreciation. Remember, self-recognition is a powerful motivator. Competing with yourself will push you forward while competing with others might drain you emotionally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus: Books for Long-Term Growth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to dig deeper into these ideas, here are a few books I recommend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Education of the Will&lt;/strong&gt; by Jules Payot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indistractable&lt;/strong&gt; by Nir Eyal &amp;amp; Julie Li&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ikigai&lt;/strong&gt; by Héctor García &amp;amp; Francesc Miralles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These books cover topics like &lt;strong&gt;understanding distractions, building resilience, and finding purpose.&lt;/strong&gt; For example, The Education of the Will is an eye-opener for identifying negative behaviors and learning how to combat them. Indistractable offers practical methods for managing distractions effectively. And if you feel something is still missing, Ikigai can help you find your life’s purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don’t see these tips as discouraging. Instead, think of them as tools to prepare for challenges and stay ahead. These methods aren’t guaranteed solutions but are based on my own experiences and what worked for me. Knowing what you’re up against and being prepared can make all the difference in your journey.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Good luck, and don’t forget — every step forward is progress!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>careerdevelopment</category>
      <category>developers</category>
      <category>beginners</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
