<?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: Jaligama Satyaveer</title>
    <description>The latest articles on DEV Community by Jaligama Satyaveer (@satyaveer_jaligama).</description>
    <link>https://dev.to/satyaveer_jaligama</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%2F2630005%2F1127dc61-a44d-49ad-9ace-02bf434cc9f4.jpg</url>
      <title>DEV Community: Jaligama Satyaveer</title>
      <link>https://dev.to/satyaveer_jaligama</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/satyaveer_jaligama"/>
    <language>en</language>
    <item>
      <title>How Browsers Render Webpages: A Deep Dive into Reflow, Paint, and Repaint</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Sat, 21 Jun 2025 07:10:20 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/how-browsers-render-webpages-a-deep-dive-into-reflow-paint-and-repaint-m5n</link>
      <guid>https://dev.to/satyaveer_jaligama/how-browsers-render-webpages-a-deep-dive-into-reflow-paint-and-repaint-m5n</guid>
      <description>&lt;p&gt;If you’ve ever built a webpage and noticed things getting a bit laggy after adding styles or dynamic elements, you’ve likely triggered something under the hood - like reflow, repaint, or paint.&lt;/p&gt;

&lt;p&gt;Don’t worry - these terms might sound complex at first, but they’re actually pretty straightforward once you get the hang of them. Let’s break them down together with real-world examples you can relate to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Big Picture: How a Web Page is Rendered&lt;/strong&gt;&lt;br&gt;
When a browser loads a webpage, it follows a process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parses HTML → Creates the DOM Tree&lt;/li&gt;
&lt;li&gt;Parses CSS → Builds the CSSOM Tree&lt;/li&gt;
&lt;li&gt;Combines DOM + CSSOM → Builds the Render Tree&lt;/li&gt;
&lt;li&gt;Performs Layout → Decides the size and position of each element&lt;/li&gt;
&lt;li&gt;Paints → Fills in colors, borders, text, shadows&lt;/li&gt;
&lt;li&gt;Composites → Draws everything on the screen&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;u&gt;Reflow (aka Layout)&lt;/u&gt;
&lt;/h2&gt;

&lt;p&gt;Reflow happens when the browser needs to figure out where and how elements should appear on the page - basically recalculating the layout.&lt;/p&gt;

&lt;p&gt;Any time you change something that affects an element’s size or position - boom, reflow kicks in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
Imagine you have a blog post with a &lt;code&gt;Read more&lt;/code&gt; button. When someone clicks it, more content shows up, pushing the rest of the page down. The browser has to recalculate the layout to fit everything in - that’s reflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;u&gt;Paint&lt;/u&gt;
&lt;/h2&gt;

&lt;p&gt;Paint is the step where the browser actually fills in the pixels - adding colors, borders, shadows, images, text… basically everything you see.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;u&gt;Repaint&lt;/u&gt;
&lt;/h2&gt;

&lt;p&gt;Repaint is a type of paint that happens when an element’s visual appearance changes, but its size or position doesn’t.&lt;/p&gt;

&lt;p&gt;So, if you change something like the color, opacity, or visibility of an element, the browser can skip layout calculations and just update the pixels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
Think about switching your website from light mode to dark mode. Text becomes white, backgrounds turn black, but nothing shifts in layout. That’s repaint.&lt;/p&gt;




&lt;p&gt;Think of your browser as an artist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reflow&lt;/strong&gt; is sketching where everything goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paint&lt;/strong&gt; is coloring in those sketches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repaint&lt;/strong&gt; is touching up the colors without redrawing everything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you understand what triggers these processes, you start to write better, faster code - and your users feel the difference.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>browser</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Faster Loads with Smaller Bundles: The Power of Dynamic Imports in Next.js</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Fri, 04 Apr 2025 19:11:32 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/faster-loads-with-smaller-bundles-the-power-of-dynamic-imports-in-nextjs-11a7</link>
      <guid>https://dev.to/satyaveer_jaligama/faster-loads-with-smaller-bundles-the-power-of-dynamic-imports-in-nextjs-11a7</guid>
      <description>&lt;p&gt;In today’s web world, speed is everything. Users expect pages to load instantly, and even a slight delay can lead to frustration or bounce. One big factor that impacts performance is your app’s bundle size - the amount of JavaScript the browser has to download and execute before the page is usable.&lt;/p&gt;

&lt;p&gt;So let’s talk about something simple, yet super effective: Dynamic Imports in Next.js&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should You Care About Bundle Size?
&lt;/h2&gt;

&lt;p&gt;A large JavaScript bundle means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Longer download times, especially on slow connections&lt;/li&gt;
&lt;li&gt;Delays before the app becomes interactive&lt;/li&gt;
&lt;li&gt;Poor performance scores and user experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the flip side, a smaller bundle means faster loads, snappier UI, and happy users.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Dynamic Import?
&lt;/h2&gt;

&lt;p&gt;In a typical React or Next.js app, components are imported at the top of the file like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import MyComponent from './MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the component is bundled into the main JavaScript file, whether it’s used immediately or not.&lt;/p&gt;

&lt;p&gt;With Next.js, you can use &lt;code&gt;next/dynamic&lt;/code&gt; to import a component only when it’s needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MyComponent = dynamic(() =&amp;gt; import('./MyComponent'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example: With vs Without Dynamic Import
&lt;/h2&gt;

&lt;p&gt;Let’s say we have a simple page that includes three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Button&lt;/li&gt;
&lt;li&gt;A Test Component&lt;/li&gt;
&lt;li&gt;A Hidden Component (only shown after a button click)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Without Dynamic Import&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;"use client";
import { useState } from "react";
import HiddenComponent from "../components/HiddenComponent";
import TestComponent from "../components/TestComponent";

export default function WithoutDynamicImport() {
  const [displayHiddenComponent, setDisplayHiddenComponent] = useState(false);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h3&amp;gt;Without Dynamic Import&amp;lt;/h3&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setDisplayHiddenComponent(!displayHiddenComponent)}&amp;gt;
        Show Hidden Component
      &amp;lt;/button&amp;gt;
      &amp;lt;TestComponent /&amp;gt;
      {displayHiddenComponent &amp;amp;&amp;amp; &amp;lt;HiddenComponent /&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this version, all components are imported statically. Even if the &lt;code&gt;HiddenComponent&lt;/code&gt;is never shown, it still gets bundled and downloaded upfront&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Dynamic Import&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;"use client";
import dynamic from "next/dynamic";
import { useState } from "react";

const HiddenComponent = dynamic(() =&amp;gt; import("../components/HiddenComponent"), {
  ssr: false,
});

const TestComponent = dynamic(() =&amp;gt; import("../components/TestComponent"), {
  ssr: false,
});

export default function WithDynamicImport() {
  const [displayHiddenComponent, setDisplayHiddenComponent] = useState(false);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h3&amp;gt;With Dynamic Import&amp;lt;/h3&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setDisplayHiddenComponent(!displayHiddenComponent)}&amp;gt;
        Show Hidden Component
      &amp;lt;/button&amp;gt;
      &amp;lt;TestComponent /&amp;gt;
      {displayHiddenComponent &amp;amp;&amp;amp; &amp;lt;HiddenComponent /&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this version, &lt;code&gt;TestComponent&lt;/code&gt;and &lt;code&gt;HiddenComponent&lt;/code&gt;are loaded only when needed. You’ll even notice separate &lt;code&gt;.js&lt;/code&gt; files being fetched in the browser when these components render for the first time&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens Behind the Scenes?
&lt;/h2&gt;

&lt;p&gt;When you use dynamic imports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component is excluded from the initial JS bundle.&lt;/li&gt;
&lt;li&gt;A separate network request is made only the first time the component is needed.&lt;/li&gt;
&lt;li&gt;Once loaded, the component is cached by the browser, so subsequent uses do not trigger another network request.&lt;/li&gt;
&lt;li&gt;This leads to faster page load, and better user experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/FhVi4NvFOis"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
Code:- &lt;a href="https://github.com/Satyaveerjaligama/dynamic-import-of-component" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Dynamic imports are a smart and simple way to keep your Next.js app lean and fast. By loading components only when they're actually needed, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce your initial JavaScript payload&lt;/li&gt;
&lt;li&gt;Improve performance and speed&lt;/li&gt;
&lt;li&gt;Make your app more scalable as it grows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start using dynamic imports for any non-critical UI - like modals, charts, tooltips, and components hidden behind interactions.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Stop Storing Plain Text Passwords! Use Bcrypt for Security</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Sat, 29 Mar 2025 19:14:02 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/stop-storing-plain-text-passwords-use-bcrypt-for-security-41fe</link>
      <guid>https://dev.to/satyaveer_jaligama/stop-storing-plain-text-passwords-use-bcrypt-for-security-41fe</guid>
      <description>&lt;p&gt;When building an application that requires user authentication, one of the worst mistakes you can make is storing passwords in plain text. If your database gets hacked, attackers can see all user credentials instantly. That’s a huge security risk!&lt;/p&gt;

&lt;p&gt;Instead, passwords should always be stored in a hashed format. Hashing transforms a password into an unreadable string, making it nearly impossible to reverse-engineer. But simple hashing isn’t enough, adding salting and key stretching makes passwords even more secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Hashing, Salting, and Key Stretching?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hashing&lt;/strong&gt;&lt;br&gt;
Hashing is a one-way function that converts a password into a fixed-length, irreversible string. This ensures that even if someone gains access to the database, they cannot retrieve the original password.&lt;/p&gt;

&lt;p&gt;If we hash the password &lt;code&gt;password123&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;EF92B778BAF9C3D1C6CFE1C4A7316C83E4F2E9F288D5A68B84BC7E0549A9AFA3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Salting&lt;/strong&gt;&lt;br&gt;
Salting adds a unique random value to each password before hashing. This ensures that even if two users have the same password, their hashes will be different.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Password: password123
Salt: X7!a9@
Hashed Output: Hash(password123 + X7!a9@)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each time a password is stored, a different salt is generated, making attacks significantly harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Stretching&lt;/strong&gt;&lt;br&gt;
Key stretching is a technique that increases the computational time required to hash a password, making brute-force attacks more difficult. This is achieved by repeatedly applying the hashing algorithm multiple times.&lt;/p&gt;

&lt;p&gt;Instead of hashing once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hash(password123)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We hash multiple times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hash(Hash(Hash(password123)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This increases the time required for attackers to compute password hashes, thereby enhancing security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Bcrypt?
&lt;/h2&gt;

&lt;p&gt;Bcrypt is one of the best tools for hashing passwords, because it automatically includes salting and key stretching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Bcrypt coverts plain text into hash before storing in Database&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a salt (a random value).&lt;/li&gt;
&lt;li&gt;Combine the password with the salt.&lt;/li&gt;
&lt;li&gt;Apply multiple rounds of hashing (key stretching) to slow down attacks.&lt;/li&gt;
&lt;li&gt;Store the final hashed password in the database.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const hashedPassword = await bcrypt.hash(password, 10);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How Bcrypt Compares Passwords&lt;/strong&gt;&lt;br&gt;
When a user logs in, we need to check if their password matches the stored hash.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the stored hashed password from the database.&lt;/li&gt;
&lt;li&gt;Extract the salt from the stored hash.&lt;/li&gt;
&lt;li&gt;Hash the user-entered password using the extracted salt.&lt;/li&gt;
&lt;li&gt;Compare the newly generated hash with the stored hash.&lt;/li&gt;
&lt;li&gt;If they match, grant access; otherwise, deny access.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const isMatch = await bcrypt.compare(enteredPassword, storedHash);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summing It Up
&lt;/h2&gt;

&lt;p&gt;Security should never be an afterthought, especially when dealing with user passwords. Bcrypt makes it easy to implement strong password hashing with salting, key stretching, and adaptability. By using bcrypt, you can protect user data and significantly reduce the risk of password-related breaches.&lt;/p&gt;

</description>
      <category>passwordhashing</category>
      <category>securepasswords</category>
      <category>dataprotection</category>
      <category>security</category>
    </item>
    <item>
      <title>How Token-Based Authentication Works: A Practical Walkthrough</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Wed, 26 Mar 2025 19:03:13 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/how-token-based-authentication-works-a-practical-walkthrough-3bjb</link>
      <guid>https://dev.to/satyaveer_jaligama/how-token-based-authentication-works-a-practical-walkthrough-3bjb</guid>
      <description>&lt;p&gt;Authentication is essential for securing web applications. In this article, I will explain token-based authentication using a real-world example of a login system built with React, Node.js, and MongoDB. If you're new to this, don't worry! I’ll guide you step by step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Does Token-Based Authentication Work?&lt;/strong&gt;&lt;br&gt;
Imagine you’re logging into an app. Here’s what happens behind the scenes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You register an account by entering your email/phone, name, and password.&lt;/li&gt;
&lt;li&gt;You log in by providing your email/phone and password.&lt;/li&gt;
&lt;li&gt;If your credentials are correct, a token is generated and sent to your device.&lt;/li&gt;
&lt;li&gt;Every time you access a protected page, your token is checked to verify your identity.&lt;/li&gt;
&lt;li&gt;If the token is valid, you can proceed. If not, you’ll be asked to log in again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This token acts like a temporary digital key, allowing access without needing to log in repeatedly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: User Registration
&lt;/h2&gt;

&lt;p&gt;When signing up, you provide details like your email/phone, name, and password. Your password is securely stored in the database using a method called hashing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your email or phone number is already registered, you’ll get an error message.&lt;/li&gt;
&lt;li&gt;If everything is correct, your account is created, and you can log in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once registered, you can move to the login step.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Logging In and Token Generation
&lt;/h2&gt;

&lt;p&gt;When you log in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your credentials are sent to the server.&lt;/li&gt;
&lt;li&gt;The server checks if the email/phone exists in the database.&lt;/li&gt;
&lt;li&gt;If the user exists, it compares your entered password with the stored password.&lt;/li&gt;
&lt;li&gt;If the password is correct, the server generates a JWT token and sends it back.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code for Token Generation (Backend)&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;const token = jwt.sign(
  { userId: existingUser._id },
  process.env.JWT_SECRET_KEY!,
  { expiresIn: "15s" } // Token expires in 15 seconds
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This token contains the user's ID and has an expiration time (15 seconds in this example, but in real-world apps, it is much longer).&lt;/p&gt;

&lt;p&gt;Once received, the token is stored in the browser so the user doesn’t have to log in again immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Accessing a Protected Page
&lt;/h2&gt;

&lt;p&gt;Now that you're logged in, you want to access a protected page (like your profile or dashboard). Here’s how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You click on a button (e.g., "View Profile").&lt;/li&gt;
&lt;li&gt;Your browser attaches the token to the request.&lt;/li&gt;
&lt;li&gt;The server checks if the token is valid.&lt;/li&gt;
&lt;li&gt;If the token is valid, the server allows access.&lt;/li&gt;
&lt;li&gt;If the token is missing, invalid, or expired, the server denies access and redirects you to the login page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code for Token Validation (Backend)&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;const authMiddleware = (req, res, next) =&amp;gt; {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) {
    return res.status(401).json({ message: "Unauthorized" });
  }
  try {
    const decodedToken = jwt.verify(token, process.env.JWT_SECRET_KEY!);
    req.user = decodedToken.userId;
    next();
  } catch (err) {
    return res.status(401).json({ message: "Unauthorized" });
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the token is valid, you can access the page. Otherwise, you’re redirected to log in again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: What Happens When the Token Expires?
&lt;/h2&gt;

&lt;p&gt;Tokens are temporary for security reasons. When a token expires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your next request will be rejected with a 401 (Unauthorized) error.&lt;/li&gt;
&lt;li&gt;You will be redirected to the login page to re-authenticate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that only active users can access protected data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QCG7HGT5M8g"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Repo Links
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Satyaveerjaligama/authentication-app-frontend" rel="noopener noreferrer"&gt;Frontend&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Satyaveerjaligama/authentication-app-backend" rel="noopener noreferrer"&gt;Backend&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Token-based authentication is a modern and secure way to manage user sessions in web applications. Applications become more secure, scalable, and efficient, ensuring a smooth user experience while protecting sensitive data.&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>jwt</category>
      <category>webapp</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Optimizing JavaScript Event Handling: Bubbling and Delegation</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Sat, 22 Mar 2025 07:47:38 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/optimizing-javascript-event-handling-bubbling-and-delegation-2681</link>
      <guid>https://dev.to/satyaveer_jaligama/optimizing-javascript-event-handling-bubbling-and-delegation-2681</guid>
      <description>&lt;p&gt;JavaScript events are everywhere on the web. Clicking a button, typing in a text box, or even moving your mouse triggers an event. But have you ever wondered how these events travel through the DOM? That’s where event bubbling and event delegation come into play.&lt;/p&gt;

&lt;p&gt;Let’s break it down in a way that actually makes sense!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Event in JavaScript?
&lt;/h2&gt;

&lt;p&gt;Before jumping into bubbling and delegation, let’s quickly define what an event is. An event is basically an action that happens in the browser, like a click or a key press. You can listen to these events using JavaScript and decide what happens when they occur.&lt;/p&gt;

&lt;p&gt;Here’s a simple example of handling a button click:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const button = document.getElementById("myButton");
button.addEventListener("click", () =&amp;gt; {
    alert("You clicked the button!");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What is Event Bubbling?
&lt;/h2&gt;

&lt;p&gt;Event bubbling is when an event starts at the target element and moves up through its ancestors. Think of it like bubbles in water - once they are created, they rise to the top.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Event Bubbling Works&lt;/strong&gt;&lt;br&gt;
Imagine this HTML structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div id="parent"&amp;gt;
    &amp;lt;button id="child"&amp;gt;Click Me&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s add event listeners to both the parent &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and the child &lt;code&gt;&amp;lt;button&amp;gt;&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;document.getElementById("parent").addEventListener("click", () =&amp;gt; {
    console.log("Parent clicked");
});

document.getElementById("child").addEventListener("click", () =&amp;gt; {
    console.log("Child clicked");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What Happens When You Click the Button?&lt;/strong&gt;&lt;br&gt;
When you click the button, you’ll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Child clicked
Parent clicked
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? Because the event first fires on the button and then bubbles up to the parent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stopping Event Bubbling&lt;/strong&gt;&lt;br&gt;
Sometimes, you don’t want an event to bubble up. You can stop it using &lt;code&gt;event.stopPropagation()&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;document.getElementById("child").addEventListener("click", (event) =&amp;gt; {
    console.log("Child clicked");
    event.stopPropagation();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, clicking the button will only log &lt;code&gt;Child clicked&lt;/code&gt; and won’t trigger the parent’s event.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Event Delegation?
&lt;/h2&gt;

&lt;p&gt;Instead of adding event listeners to multiple elements, you can use event delegation by placing a listener on a parent element and checking which child was clicked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use Event Delegation?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t have to attach event listeners to each individual child element.&lt;/li&gt;
&lt;li&gt;It works on dynamically added elements.&lt;/li&gt;
&lt;li&gt;It improves performance when dealing with lots of elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example: Handling Clicks on List Items&lt;/strong&gt;&lt;br&gt;
Consider this HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul id="listContainer"&amp;gt;
    &amp;lt;li class="list-item"&amp;gt;Item 1&amp;lt;/li&amp;gt;
    &amp;lt;li class="list-item"&amp;gt;Item 2&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;button id="addItem"&amp;gt;Add Item&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of adding an event listener to each list item, we add one to the parent &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; and check which item was clicked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.getElementById("listContainer").addEventListener("click", (event) =&amp;gt; {
    if (event.target.classList.contains("list-item")) {
        console.log("Clicked on: " + event.target.textContent);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s add new list items dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.getElementById("addItem").addEventListener("click", () =&amp;gt; {
    const newItem = document.createElement("li");
    newItem.classList.add("list-item");
    newItem.textContent = "New Item";
    document.getElementById("listContainer").appendChild(newItem);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though the new list items were added later, they will still trigger the click event. That’s the power of event delegation!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Understanding event bubbling helps you know how events travel up the DOM, and event delegation helps you manage events efficiently. Together, they make your JavaScript code cleaner and more optimized.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>eventhandling</category>
    </item>
    <item>
      <title>Understanding WebSockets: Real-Time Data Transfer Made Easy</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Tue, 25 Feb 2025 21:12:53 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/understanding-websockets-real-time-data-transfer-made-easy-3ghj</link>
      <guid>https://dev.to/satyaveer_jaligama/understanding-websockets-real-time-data-transfer-made-easy-3ghj</guid>
      <description>&lt;p&gt;WebSockets are commonly used in applications that require real-time updates and bidirectional communication between the client and server. They are ideal for chat applications, financial dashboards and payment status tracking. In this article, we will explore how WebSockets can be implemented to provide instant payment status updates in a web application.&lt;/p&gt;

&lt;p&gt;In traditional systems, the frontend would need to keep checking the payment status through repeated API calls. With WebSockets, the server can emit events as soon as the payment is processed, reducing unnecessary API calls and improving efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Down the WebSockets Implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Frontend&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Initializing WebSocket Connection&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;import { io } from "socket.io-client";

const socket = io(process.env.API_BASE_URL, { autoConnect: false });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The frontend initializes a WebSocket connection to the backend using &lt;code&gt;io(process.env.API_BASE_URL, { autoConnect: false })&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;autoConnect: false&lt;/code&gt; ensures that the socket does not connect automatically until explicitly called.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Handling Connection and Events&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;useEffect(() =&amp;gt; {
  socket.connect();

  socket.on("socket-id", setSocketId);
  socket.on("payment-status", setPaymentStatus);

  return () =&amp;gt; {
    socket.off("socket-id");
    socket.off("payment-status");
    socket.disconnect();
  };
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;socket.connect()&lt;/code&gt; establishes the connection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Listens for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;socket-id&lt;/code&gt;: Receives and stores the unique identifier assigned by the server.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;payment-status&lt;/code&gt;: Updates the payment status in real-time.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Cleanup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;socket.off(...)&lt;/code&gt; ensures that event listeners are removed when the component unmounts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;socket.disconnect()&lt;/code&gt; properly closes the connection.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Sending Data to Backend&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;await axios.post(
  `${process.env.API_BASE_URL}/api/payments/make-payment-with-socket`,
  { amount: 1000, socketId }
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The client sends a payment request to the backend API, including the &lt;code&gt;socketId&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This ensures the server knows which client to send the payment status update to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Backend&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Setting Up WebSockets (socket.js)&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;const { Server } = require("socket.io");

let io;

const setupSocket = (server) =&amp;gt; {
  io = new Server(server, {
    cors: { origin: "http://localhost:3000" },
  });

  io.on("connection", (socket) =&amp;gt; {
    console.log(`User connected: ${socket.id}`);
    socket.emit("socket-id", socket.id);

    socket.on("disconnect", () =&amp;gt;
      console.log(`User disconnected: ${socket.id}`)
    );
  });
};

const emitPaymentStatus = (socketId, status) =&amp;gt; {
  if (io) io.to(socketId).emit("payment-status", status);
};

module.exports = { setupSocket, emitPaymentStatus };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;setupSocket(server)&lt;/code&gt;: Initializes the WebSocket server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Handles Connections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a client connects, it assigns a unique &lt;code&gt;socket.id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It sends the &lt;code&gt;socket-id&lt;/code&gt; back to the client.&lt;/li&gt;
&lt;li&gt;It listens for disconnection events.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Emitting Events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;emitPaymentStatus&lt;/code&gt; function emits the &lt;code&gt;payment-status&lt;/code&gt; event to a specific client using their &lt;code&gt;socketId&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Integrating WebSockets with Express (index.js)&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;const express = require("express");
const http = require("http");
const { setupSocket } = require("./socket");

const app = express();
const server = http.createServer(app);
setupSocket(server);

server.listen(PORT, () =&amp;gt; {
  console.log(`Backend server running on port ${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;http.createServer(app)&lt;/code&gt;: Creates an HTTP server to attach WebSockets to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;setupSocket(server)&lt;/code&gt;: Passes the server to the WebSocket setup function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;server.listen(PORT)&lt;/code&gt;: Starts the backend server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Emitting Events After Payment (paymentRoutes.js)&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;const { emitPaymentStatus } = require("../socket");

router.post("/make-payment-with-socket", (req, res) =&amp;gt; {
  const { socketId } = req.body;

  setTimeout(() =&amp;gt; {
    emitPaymentStatus(socketId, true);
  }, 10000);

  res.status(200).json({ message: "Payment received, processing request" });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The backend receives the &lt;code&gt;socketId&lt;/code&gt; from the frontend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simulates payment processing with &lt;code&gt;setTimeout()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calls &lt;code&gt;emitPaymentStatus(socketId, true)&lt;/code&gt; to notify the client of a successful payment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Check Payment status - Without WebSocket&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-7CExalGHsc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Check Payment status - With WebSocket&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/aza5afhwSCU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Code&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/Satyaveerjaligama/websockets-frontend" rel="noopener noreferrer"&gt;Frontend&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Satyaveerjaligama/websockets-backend" rel="noopener noreferrer"&gt;Backend&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;WebSockets enable real-time, event-driven communication between the client and server, significantly reducing the need for repeated API polling. This improves efficiency, reduces server load, and enhances user experience. By implementing WebSockets in the payment processing system, we eliminate unnecessary requests and enable instant status updates.&lt;/p&gt;

</description>
      <category>websockets</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Debouncing Made Simple: Improve React Performance with Delayed Execution</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Sun, 16 Feb 2025 15:57:21 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/debouncing-made-simple-improve-react-performance-with-delayed-execution-5gm2</link>
      <guid>https://dev.to/satyaveer_jaligama/debouncing-made-simple-improve-react-performance-with-delayed-execution-5gm2</guid>
      <description>&lt;p&gt;Debouncing is a programming technique used to limit the rate at which a function executes. It is particularly useful when dealing with events that fire frequently, such as keystrokes, API calls etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Debouncing?
&lt;/h2&gt;

&lt;p&gt;For example, when users type in a search box, the input event is triggered every time a key is pressed. Without debouncing, an API call would be made on every keystroke, causing unnecessary network requests. Debouncing ensures that the function (e.g., API call) executes only after the user has stopped typing for a certain period.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Debouncing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Setting up state&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;const [fieldValue, setFieldValue] = useState("");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. API Call Function&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;const getData = () =&amp;gt; {
  console.log("----API Call----");
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function simulates an API call by logging &lt;code&gt;"----API Call----"&lt;/code&gt; to the console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Implementing Debouncing using useEffect&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;useEffect(() =&amp;gt; {
  const apiCallTimeout = setTimeout(() =&amp;gt; {
    getData();
  }, 2000);

  return () =&amp;gt; clearTimeout(apiCallTimeout);
}, [fieldValue]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Whenever &lt;code&gt;fieldValue&lt;/code&gt; changes, the effect runs.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;setTimeout&lt;/code&gt; is set for 2000 milliseconds (2 seconds) to call &lt;code&gt;getData()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the user continues typing before the 2-second delay, the previous &lt;code&gt;setTimeout&lt;/code&gt; is cleared, and a new one starts.&lt;/li&gt;
&lt;li&gt;The cleanup function (&lt;code&gt;return () =&amp;gt; clearTimeout(apiCallTimeout);&lt;/code&gt;) ensures that only the last keystroke (after the user stops typing) triggers the API call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Without Debouncing&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;// useEffect(() =&amp;gt; {
//   getData();
// }, [fieldValue]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If this version is used, &lt;code&gt;getData()&lt;/code&gt; would run every time &lt;code&gt;fieldValue&lt;/code&gt; changes, causing multiple API calls for every keystroke.&lt;/li&gt;
&lt;li&gt;This leads to unnecessary network requests and potential performance issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Input Field&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;return (
  &amp;lt;div className="App"&amp;gt;
    &amp;lt;input
      type="text"
      onChange={(e) =&amp;gt; setFieldValue(e.target.value)}
      value={fieldValue}
      placeholder="Search"
    /&amp;gt;
  &amp;lt;/div&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from "react";

function DebouncingExample() {
  const [fieldValue, setFieldValue] = useState("");

  const getData = () =&amp;gt; {
    console.log("----API Call----");
  };

  // ------------------Debouncing--------------------
  useEffect(() =&amp;gt; {
    const apiCallTimeout = setTimeout(() =&amp;gt; {
      getData();
    }, 2000);

    return () =&amp;gt; clearTimeout(apiCallTimeout);
  }, [fieldValue]);

  // ----------------Without debouncing------------------
  // useEffect(() =&amp;gt; {
  //   getData();
  // }, [fieldValue]);

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;input
        type="text"
        onChange={(e) =&amp;gt; setFieldValue(e.target.value)}
        value={fieldValue}
        placeholder="Search"
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default DebouncingExample;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Debouncing is an essential technique to improve performance and avoid excessive function executions. In this case, it helps prevent multiple API calls on every keystroke by delaying execution until the user pauses typing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is widely used in search boxes, form validations, and resize events to improve efficiency and user experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>debouncing</category>
    </item>
    <item>
      <title>The Deprecation of Create React App</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Sun, 16 Feb 2025 06:52:03 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/the-deprecation-of-create-react-app-1mh4</link>
      <guid>https://dev.to/satyaveer_jaligama/the-deprecation-of-create-react-app-1mh4</guid>
      <description>&lt;p&gt;On February 14, 2025, the React team &lt;a href="https://react.dev/blog/2025/02/14/sunsetting-create-react-app" rel="noopener noreferrer"&gt;officially announced&lt;/a&gt; the deprecation of Create React App (CRA) for new applications, urging developers to migrate to modern frameworks.&lt;/p&gt;

&lt;p&gt;Back in 2016, setting up a new React app was complicated. Developers had to configure tools like Webpack, Babel, ESLint etc manually. To solve this, Create React App (CRA) was introduced as an all-in-one tool that provided a zero-config setup for React projects, making it easy to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why CRA is Being Deprecated
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;No Active Maintainers&lt;/li&gt;
&lt;li&gt;Poor Performance for Production Apps&lt;/li&gt;
&lt;li&gt;Lack of Modern React Features and due to several other limitations.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Limitations of CRA
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Routing&lt;/strong&gt;&lt;br&gt;
CRA did not include a routing solution, developers had to manually install React Router or similar libraries.&lt;/p&gt;

&lt;p&gt;With frameworks like Next.js, routing is built-in, making navigation seamless and structured from the start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Splitting &amp;amp; Performance&lt;/strong&gt;&lt;br&gt;
CRA bundled all JavaScript files into a single large file, causing slow initial page loads. While manual code splitting was possible, it wasn’t the most efficient approach.&lt;/p&gt;

&lt;p&gt;Newer frameworks like Next.js automatically handle code-splitting at the route level, ensuring users only download the code they need for the page they are visiting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poor Production Readiness&lt;/strong&gt;&lt;br&gt;
While CRA was excellent for prototyping, it lacked optimizations required for production applications. Features like SSR (Server-Side Rendering), static site generation (SSG) were completely missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended Alternatives
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;br&gt;
A feature-rich framework with SSR, SSG, API routes, and automatic code-splitting. Best for scalable web apps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;br&gt;
A fast, lightweight alternative for those who want a simple yet efficient build tool without extra complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The deprecation of CRA marks a shift towards more optimized, performant, and scalable solutions for building React applications. While CRA played a vital role in React’s growth, modern frameworks like Next.js, and Vite provide a better developer experience and ensure production-grade performance.&lt;/p&gt;

</description>
      <category>createreactapp</category>
      <category>react</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Choosing the Right CSS Approach for Your React Application</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Mon, 10 Feb 2025 16:39:22 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/choosing-the-right-css-approach-for-your-react-application-3ohk</link>
      <guid>https://dev.to/satyaveer_jaligama/choosing-the-right-css-approach-for-your-react-application-3ohk</guid>
      <description>&lt;p&gt;When working on a React application, there are multiple ways to style components. The choice of approach depends on individual preference, project requirements, and team decisions. Below are the five common CSS approaches used in React applications.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Standard CSS&lt;/li&gt;
&lt;li&gt;CSS Modules&lt;/li&gt;
&lt;li&gt;Preprocessors (Sass/Scss)&lt;/li&gt;
&lt;li&gt;Utility-First CSS Framework (Tailwind CSS)&lt;/li&gt;
&lt;li&gt;CSS-in-JS (Styled Components)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Standard CSS
&lt;/h2&gt;

&lt;p&gt;Writing CSS in external &lt;code&gt;.css&lt;/code&gt; files and importing them into React components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* styles.css */
.button {
  background-color: blue;
  color: white;
  padding: 10px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js
import './styles.css';

function App() {
  return &amp;lt;button className="button"&amp;gt;Click Here&amp;lt;/button&amp;gt;;
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  CSS Modules
&lt;/h2&gt;

&lt;p&gt;A modular approach where CSS is scoped to a specific component, preventing global conflicts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Button.module.css */
.button {
  background-color: blue;
  color: white;
  padding: 10px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Button.js
import styles from './Button.module.css';

function Button() {
  return &amp;lt;button className={styles.button}&amp;gt;Click Here&amp;lt;/button&amp;gt;;
}

export default Button;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Preprocessors (Sass/Scss)
&lt;/h2&gt;

&lt;p&gt;Extends standard CSS with features like variables, nesting, and mixins for better maintainability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* styles.scss */
$primary-color: blue;
.button {
  background-color: $primary-color;
  color: white;
  padding: 10px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js
import './styles.scss';

function App() {
  return &amp;lt;button className="button"&amp;gt;Click Here&amp;lt;/button&amp;gt;;
}
export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Utility-First CSS Framework (Tailwind CSS)
&lt;/h2&gt;

&lt;p&gt;A utility-based approach that provides pre-defined classes to style elements directly in JSX.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js
function App() {
  return &amp;lt;button className="bg-blue-500 text-white p-2"&amp;gt;Click Here&amp;lt;/button&amp;gt;;
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  CSS-in-JS (Styled Components)
&lt;/h2&gt;

&lt;p&gt;Allows defining styles directly within JavaScript using template literals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Button.js
import styled from 'styled-components';

const Button = styled.button`
  background-color: blue;
  color: white;
  padding: 10px;
`;

function App() {
  return &amp;lt;Button&amp;gt;Click Here&amp;lt;/Button&amp;gt;;
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;u&gt;Conclusion&lt;/u&gt;
&lt;/h2&gt;

&lt;p&gt;Each approach to styling in React has its benefits and drawbacks. The best choice depends on your project needs, team preferences, and maintainability concerns. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Standard CSS&lt;/code&gt; for simple projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;CSS Modules&lt;/code&gt; to prevent global style conflicts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Sass/Scss&lt;/code&gt; for better maintainability in large projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Tailwind CSS&lt;/code&gt; for rapid UI development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Styled Components&lt;/code&gt; for dynamic styling in component-based architecture.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Stack in Action: Building Undo and Redo Functionality in a Todo App</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Sat, 08 Feb 2025 21:14:17 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/stack-in-action-building-undo-and-redo-functionality-in-a-todo-app-3gcd</link>
      <guid>https://dev.to/satyaveer_jaligama/stack-in-action-building-undo-and-redo-functionality-in-a-todo-app-3gcd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When learning Data Structures and Algorithms (DSA), many developers struggle to find real-world applications for the concepts they study. One such fundamental data structure is the &lt;strong&gt;Stack&lt;/strong&gt;. While it may seem theoretical at first, stacks have many practical applications, including implementing &lt;strong&gt;Undo and Redo functionality&lt;/strong&gt; in apps.&lt;/p&gt;

&lt;p&gt;In this article, we will explore the Stack data structure and see how it can be used to implement Undo/Redo in a simple Todo App.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Stack?
&lt;/h2&gt;

&lt;p&gt;A Stack is a linear data structure that follows the &lt;strong&gt;Last In, First Out (LIFO) principle&lt;/strong&gt;. This means that the last item added to the stack is the first one to be removed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Operations of a Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Push&lt;/code&gt;: Adds an item to the top of the stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Pop&lt;/code&gt;: Removes the top item from the stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Peek (Top)&lt;/code&gt;: Returns the top item without removing it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isEmpty&lt;/code&gt;: Checks if the stack is empty.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementing Undo/Redo in a Todo App
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Application Features:&lt;/strong&gt;&lt;br&gt;
Our Todo App will have the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Text Field&lt;/code&gt;: Allows users to enter and add tasks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Undo Button&lt;/code&gt;: Removes the last task and moves it to the redo stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Redo Button&lt;/code&gt;: Restores the last undone task from the redo stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Show Stacks Button&lt;/code&gt;: Displays the contents of both the Main Stack (tasks) and the Redo Stack.&lt;/li&gt;
&lt;/ul&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%2F4r163f6cxl6pih7kc0fe.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%2F4r163f6cxl6pih7kc0fe.png" alt="todo App" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack Implementation in the Todo App:&lt;/strong&gt;&lt;br&gt;
In this implementation, we use two stacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Main Stack&lt;/code&gt;: Stores the active tasks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Redo Stack&lt;/code&gt;: Stores the undone tasks.&lt;/li&gt;
&lt;/ul&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%2Firkgzg0xf458m6j7bhbc.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%2Firkgzg0xf458m6j7bhbc.png" alt="Todo App" width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Undo/Redo Works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When a task is added, it is pushed onto the Main Stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the Undo button is clicked, the top task is popped from the Main Stack and pushed onto the Redo Stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the Redo button is clicked, the top task is popped from the Redo Stack and pushed back onto the Main Stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clicking Show Stack will display both stacks, highlighting the top item with a darker shade.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nlWEZmP3sfw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Code:- &lt;a href="https://github.com/Satyaveerjaligama/stack-implementation-in-todo-app" rel="noopener noreferrer"&gt;GitHub Link&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Stacks are a fundamental data structure with many real-world applications. Implementing Undo and Redo functionality in a Todo App is a practical way to understand stacks in action. By visualizing how tasks move between stacks, developers can better grasp the LIFO concept and its importance in application development.&lt;/p&gt;

</description>
      <category>datastructures</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Optimizing Performance with Infinite Scrolling in React</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Thu, 06 Feb 2025 19:54:59 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/optimizing-performance-with-infinite-scrolling-in-react-p9h</link>
      <guid>https://dev.to/satyaveer_jaligama/optimizing-performance-with-infinite-scrolling-in-react-p9h</guid>
      <description>&lt;p&gt;In our daily lives, we interact with many applications like Instagram, YouTube, LinkedIn, Facebook etc. If we observe carefully, the content loads continuously as we scroll. This seamless experience is achieved using infinite scrolling, a technique that keeps users engaged without interruptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Infinite Scrolling?
&lt;/h2&gt;

&lt;p&gt;Loading or processing a huge amount of data all at once during page load is not a good idea. It can negatively impact:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt; – Fetching large amounts of data at once can slow down the application.&lt;br&gt;
&lt;strong&gt;User Experience&lt;/strong&gt; – Users might face delays or lag while interacting with the application.&lt;/p&gt;

&lt;p&gt;To avoid these issues, applications implement infinite scrolling. This approach enhances engagement and provides a smooth user experience by dynamically loading content as the user scrolls.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementing Infinite Scrolling in React
&lt;/h2&gt;

&lt;p&gt;There are multiple ways to implement infinite scrolling in React. One of it is by using the &lt;code&gt;react-infinite-scroll-component&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;This library helps manage infinite scrolling efficiently by handling API calls and updating the UI without affecting performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Define State variables&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;const [items, setItems] = useState([]);
const [hasMore, setHasMore] = useState(true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;items:&lt;/code&gt; Stores the list of items displayed on the page.&lt;br&gt;
&lt;code&gt;hasMore:&lt;/code&gt; A boolean that determines whether more data is available to load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Function to Generate New Data&lt;/strong&gt;&lt;br&gt;
This function generates an array of 10 numbers, starting from a given number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const generateArray = (startFrom) =&amp;gt; {
  return Array.from({ length: 10 }, (_, index) =&amp;gt; startFrom + index);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Fetching Initial Data on Component Mount&lt;/strong&gt;&lt;br&gt;
When the component mounts, it triggers &lt;code&gt;getInitialData()&lt;/code&gt;, which simulates a delayed API call using &lt;code&gt;setTimeout()&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;useEffect(() =&amp;gt; {
  async function getInitialData() {
    setTimeout(() =&amp;gt; {
      setItems(generateArray(1));
    }, 1000);
  }
  getInitialData();
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Handling Data Fetching on Scroll&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;const getData = async () =&amp;gt; {
  if (items.length &amp;lt; 60) {
    console.log("Fetching the data after", items.length);
    setTimeout(() =&amp;gt; {
      setItems((prevItems) =&amp;gt; [
        ...prevItems,
        ...generateArray(prevItems.length + 1),
      ]);
      setHasMore(true);
    }, 1000);
  } else {
    console.log("-----------No More Data to show----------");
    setHasMore(false);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This &lt;code&gt;getData()&lt;/code&gt; function loads more data when the user scrolls down.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;items.length&lt;/code&gt; is less than 60, it fetches the next batch of 10 items.&lt;/li&gt;
&lt;li&gt;If the length reaches 60, it stops loading more data by setting &lt;code&gt;hasMore&lt;/code&gt;to &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. InfiniteScroll Component&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;&amp;lt;InfiniteScroll
  dataLength={items.length}
  next={getData}
  hasMore={hasMore}
  loader={&amp;lt;p&amp;gt;Loading....&amp;lt;/p&amp;gt;}
&amp;gt;
  {items.map((value, index) =&amp;gt; (
    &amp;lt;div
      key={value + index}
      style={{
        height: "100px",
        fontSize: "20px",
        fontWeight: "bold",
        backgroundColor: `${index % 2 === 0 ? "" : "lightblue"}`,
        marginBottom: "10px",
      }}
    &amp;gt;
      {value}
    &amp;lt;/div&amp;gt;
  ))}
&amp;lt;/InfiniteScroll&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";

function InfiniteScrollDemo() {
  const [items, setItems] = useState([]);
  const [hasMore, setHasMore] = useState(true);

  const generateArray = (startFrom) =&amp;gt; {
    return Array.from({ length: 10 }, (_, index) =&amp;gt; startFrom + index);
  };

  useEffect(() =&amp;gt; {
    async function getInitialData() {
      setTimeout(() =&amp;gt; {
        setItems(generateArray(1));
      }, 1000);
    }
    getInitialData();
  }, []);

  const getData = async () =&amp;gt; {
    if (items.length &amp;lt; 60) {
      console.log("Fetching the data after", items.length);
      setTimeout(() =&amp;gt; {
        setItems((prevItems) =&amp;gt; [
          ...prevItems,
          ...generateArray(prevItems.length + 1),
        ]);
        setHasMore(true);
      }, 1000);
    } else {
      console.log("-----------No More Data to show----------");
      setHasMore(false);
    }
  };

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;InfiniteScroll
        dataLength={items.length}
        next={getData}
        hasMore={hasMore}
        loader={&amp;lt;p&amp;gt;Loading....&amp;lt;/p&amp;gt;}
      &amp;gt;
        {items.map((value, index) =&amp;gt; (
          &amp;lt;div
            key={value + index}
            style={{
              height: "100px",
              fontSize: "20px",
              fontWeight: "bold",
              backgroundColor: `${index % 2 === 0 ? "" : "lightblue"}`,
              marginBottom: "10px",
            }}
          &amp;gt;
            {value}
          &amp;lt;/div&amp;gt;
        ))}
      &amp;lt;/InfiniteScroll&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default InfiniteScrollDemo;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;This implementation efficiently loads content in batches, ensuring that the app does not load excessive data at once. The benefits include:&lt;br&gt;
&lt;strong&gt;Better performance&lt;/strong&gt; – Only necessary data is loaded.&lt;br&gt;
&lt;strong&gt;Smooth user experience&lt;/strong&gt; – Users don’t have to wait for large data loads.&lt;br&gt;
&lt;strong&gt;Engagement-friendly&lt;/strong&gt; – Continuous scrolling keeps users active on the page.&lt;/p&gt;

</description>
      <category>infinitescrolling</category>
      <category>react</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>React 19 : useOptimistic Hook</title>
      <dc:creator>Jaligama Satyaveer</dc:creator>
      <pubDate>Wed, 01 Jan 2025 18:35:19 +0000</pubDate>
      <link>https://dev.to/satyaveer_jaligama/react-19-useoptimistic-hook-1kg</link>
      <guid>https://dev.to/satyaveer_jaligama/react-19-useoptimistic-hook-1kg</guid>
      <description>&lt;p&gt;React 19 introduced several new features, including the useOptimistic hook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useOptimistic&lt;/strong&gt; help us in updating the UI when our async function is in progress.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lets understand the use case of useOptimistic with an example
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;When a user likes a post on Instagram.&lt;/li&gt;
&lt;li&gt;Client(Instagram app on user device) will make an API call to server for updating the number of likes. (&lt;em&gt;asynchronous action&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Once client receives the response from the server, UI will be updated accordingly with correct number of likes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the server is slow, there may be a delay in receiving the response and updating the UI, leading to a poor user experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  The best way to enhance user experience
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;User likes a post on Instagram.&lt;/li&gt;
&lt;li&gt;UI will display updated likes count without any delay.&lt;/li&gt;
&lt;li&gt;Client will make an API call to server. (&lt;em&gt;asynchronous action&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;If API call is success, there will be no change in the UI (because we are already displaying updated likes count).&lt;/li&gt;
&lt;li&gt;If the API call is failed, like will be removed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;useOptimistic hook assists in managing likes while our asynchronous code (such as an API call in this case) is still underway.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;API call Success&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/08uMpwJiwCQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;API call Failed&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/jJbvp5_rX5o"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { HeartFilledIcon, HeartIcon } from "@radix-ui/react-icons";
import { Box, Strong, Text } from "@radix-ui/themes";
import { useOptimistic, useState, useTransition } from "react";

const UseOptimisticExample = () =&amp;gt; {
  const [likes, setLikes] = useState(100);
  const [isPostLiked, setIsPostLiked] = useState(false);
  const [optimisticData, setOptimisticData] = useOptimistic(
    { likes, isPostLiked },
    (currentState, newLikes) =&amp;gt; {
      return { likes: currentState.likes + newLikes, isPostLiked: true };
    }
  );
  const [, startTransition] = useTransition();

  const onLikeClick = () =&amp;gt; {
    startTransition(async () =&amp;gt; {
      setOptimisticData(1);
      //   Simulating API call
      await new Promise((resolve, reject) =&amp;gt; {
        console.log("Request sent to server");
        setTimeout(() =&amp;gt; {
          resolve(likes + 1); // To simulate API call success
          //   reject("API call failed"); // To simulate API call failure
        }, 8000);
      })
        .then((newLikes) =&amp;gt; {
          console.log("API call success");
          setLikes(newLikes);
          setIsPostLiked(true);
        })
        .catch((error) =&amp;gt; {
          console.error(error);
        });
    });
  };

  return (
    &amp;lt;Box py="1" px="2"&amp;gt;
      {optimisticData.isPostLiked ? (
        &amp;lt;HeartFilledIcon
          color="red"
          style={{ height: "50px", width: "50px", cursor: "pointer" }}
          onClick={onLikeClick}
        /&amp;gt;
      ) : (
        &amp;lt;HeartIcon
          style={{ height: "50px", width: "50px", cursor: "pointer" }}
          onClick={onLikeClick}
        /&amp;gt;
      )}
      &amp;lt;br&amp;gt;&amp;lt;/br&amp;gt;
      &amp;lt;Text&amp;gt;
        &amp;lt;Strong&amp;gt;{optimisticData.likes} Likes&amp;lt;/Strong&amp;gt;
      &amp;lt;/Text&amp;gt;
    &amp;lt;/Box&amp;gt;
  );
};

export default UseOptimisticExample;

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

&lt;/div&gt;



</description>
      <category>frontend</category>
      <category>react</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
