<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Viewport]]></title><description><![CDATA[Master new skills and advance your career with our comprehensive tech blogs. Explore a wide range of topics, from DS & Algorithms and Web development. ]]></description><link>https://yashrajxdev.blog</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1771143516993/2ddd638a-b042-4865-b1b0-90ac7fb13985.png</url><title>Viewport</title><link>https://yashrajxdev.blog</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 16:02:01 GMT</lastBuildDate><atom:link href="https://yashrajxdev.blog/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Taming Form State with useReducer: From Messy to Production-Ready]]></title><description><![CDATA[If you've already read the theory, you know that useReducer shines when state transitions are complex and interdependent. Forms are one of the best real-world cases for it. Let's build something that ]]></description><link>https://yashrajxdev.blog/taming-form-state-with-usereducer-from-messy-to-production-ready</link><guid isPermaLink="true">https://yashrajxdev.blog/taming-form-state-with-usereducer-from-messy-to-production-ready</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 28 Mar 2026 16:36:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/32c0ce6f-2240-4205-8a49-d30c86916aba.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've already <a href="https://yashrajxdev.blog/usereducer-in-react-a-simple-counter-then-the-bigger-picture">read the theory</a>, you know that <code>useReducer</code> shines when state transitions are complex and interdependent. Forms are one of the best real-world cases for it. Let's build something that actually holds up in production.</p>
<hr />
<h2>The Problem with <code>useState</code> in Complex Forms</h2>
<p>Before writing a single line of <code>useReducer</code>, here's what a typical multi-field form looks like with <code>useState</code>:</p>
<pre><code class="language-javascript">const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitStatus, setSubmitStatus] = useState(null);
</code></pre>
<p>Six separate state variables that all need to move together — especially during submission. When <code>isSubmitting</code> is <code>true</code>, you want to clear errors, lock fields, and show a spinner. You're now coordinating six <code>set*</code> calls scattered across your handlers. This is where bugs live.</p>
<p><code>useReducer</code> centralises all of that into a single, predictable state machine.</p>
<hr />
<h2>The State Shape</h2>
<p>Design the state first, before writing any reducer logic. This single decision defines everything else.</p>
<pre><code class="language-javascript">const initialState = {
  values: {
    name: '',
    email: '',
    password: '',
    confirmPassword: '',
  },
  errors: {
    name: null,
    email: null,
    password: null,
    confirmPassword: null,
  },
  touched: {
    name: false,
    email: false,
    password: false,
    confirmPassword: false,
  },
  isSubmitting: false,
  submitStatus: null, // 'success' | 'error' | null
};
</code></pre>
<p>Three sub-objects matter here: <code>values</code> holds raw input, <code>errors</code> holds validation messages (or <code>null</code> when clean), and <code>touched</code> tracks whether the user has interacted with a field. Showing errors only on touched fields is the behaviour users actually expect.</p>
<hr />
<h2>The Action Types</h2>
<p>Keep these as constants. String literals scattered across a codebase are a maintenance hazard.</p>
<pre><code class="language-javascript">const ACTIONS = {
  SET_FIELD: 'SET_FIELD',
  SET_TOUCHED: 'SET_TOUCHED',
  SET_ERROR: 'SET_ERROR',
  SET_ERRORS: 'SET_ERRORS',
  SUBMIT_START: 'SUBMIT_START',
  SUBMIT_SUCCESS: 'SUBMIT_SUCCESS',
  SUBMIT_FAILURE: 'SUBMIT_FAILURE',
  RESET: 'RESET',
};
</code></pre>
<hr />
<h2>The Reducer</h2>
<p>This is the core. Every state transition lives here, nowhere else.</p>
<pre><code class="language-js">function formReducer(state, action) {
  switch (action.type) {
    case ACTIONS.SET_FIELD:
      return {
        ...state,
        values: {
          ...state.values,
          [action.field]: action.value,
        },
        // Clear the error as soon as the user starts correcting
        errors: {
          ...state.errors,
          [action.field]: null,
        },
      };

    case ACTIONS.SET_TOUCHED:
      return {
        ...state,
        touched: {
          ...state.touched,
          [action.field]: true,
        },
      };

    case ACTIONS.SET_ERROR:
      return {
        ...state,
        errors: {
          ...state.errors,
          [action.field]: action.message,
        },
      };

    case ACTIONS.SET_ERRORS:
      return {
        ...state,
        errors: {
          ...state.errors,
          ...action.errors,
        },
      };

    case ACTIONS.SUBMIT_START:
      return {
        ...state,
        isSubmitting: true,
        submitStatus: null,
        errors: Object.fromEntries(
          Object.keys(state.errors).map((k) =&gt; [k, null])
        ),
      };

    case ACTIONS.SUBMIT_SUCCESS:
      return {
        ...initialState,
        submitStatus: 'success',
      };

    case ACTIONS.SUBMIT_FAILURE:
      return {
        ...state,
        isSubmitting: false,
        submitStatus: 'error',
        errors: action.errors || state.errors,
      };

    case ACTIONS.RESET:
      return initialState;

    default:
      return state;
  }
}
</code></pre>
<p>Notice what <code>SUBMIT_START</code> does: it clears all errors in one shot and sets <code>isSubmitting</code> atomically. With <code>useState</code>, this is four separate calls. Here it's one dispatch, one render cycle. The <code>SUBMIT_SUCCESS</code> case resets to <code>initialState</code> but preserves <code>submitStatus: 'success'</code> so you can show a confirmation message.</p>
<hr />
<h2>The Validation Layer</h2>
<p>Keep validation completely separate from state logic. It's a pure function — same input, same output, no side effects.</p>
<pre><code class="language-js">function validate(values) {
  const errors = {};

  if (!values.name.trim()) {
    errors.name = 'Name is required.';
  } else if (values.name.trim().length &lt; 2) {
    errors.name = 'Name must be at least 2 characters.';
  }

  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!values.email) {
    errors.email = 'Email is required.';
  } else if (!emailRegex.test(values.email)) {
    errors.email = 'Please enter a valid email address.';
  }

  if (!values.password) {
    errors.password = 'Password is required.';
  } else if (values.password.length &lt; 8) {
    errors.password = 'Password must be at least 8 characters.';
  } else if (!/[A-Z]/.test(values.password)) {
    errors.password = 'Password must contain at least one uppercase letter.';
  }

  if (!values.confirmPassword) {
    errors.confirmPassword = 'Please confirm your password.';
  } else if (values.password !== values.confirmPassword) {
    errors.confirmPassword = 'Passwords do not match.';
  }

  return errors; // Empty object = no errors
}
</code></pre>
<hr />
<h2>The Custom Hook</h2>
<p>Wrap all the dispatch logic into a custom hook. Your component should never know what <code>dispatch</code> is — it should only see named, intention-revealing handlers.</p>
<pre><code class="language-js">import { useReducer, useCallback } from 'react';

function useSignupForm() {
  const [state, dispatch] = useReducer(formReducer, initialState);

  const handleChange = useCallback((field, value) =&gt; {
    dispatch({ type: ACTIONS.SET_FIELD, field, value });
  }, []);

  const handleBlur = useCallback(
    (field) =&gt; {
      dispatch({ type: ACTIONS.SET_TOUCHED, field });

      // Validate the single field on blur
      const errors = validate(state.values);
      if (errors[field]) {
        dispatch({
          type: ACTIONS.SET_ERROR,
          field,
          message: errors[field],
        });
      }
    },
    [state.values]
  );

  const handleSubmit = useCallback(
    async (e) =&gt; {
      e.preventDefault();

      const errors = validate(state.values);
      const hasErrors = Object.keys(errors).length &gt; 0;

      if (hasErrors) {
        // Mark all fields as touched so every error becomes visible
        dispatch({ type: ACTIONS.SET_ERRORS, errors });
        Object.keys(state.values).forEach((field) =&gt; {
          dispatch({ type: ACTIONS.SET_TOUCHED, field });
        });
        return;
      }

      dispatch({ type: ACTIONS.SUBMIT_START });

      try {
        // Replace this with your actual API call
        await fakeApiCall(state.values);
        dispatch({ type: ACTIONS.SUBMIT_SUCCESS });
      } catch (apiError) {
        dispatch({
          type: ACTIONS.SUBMIT_FAILURE,
          errors: apiError.fieldErrors || {},
        });
      }
    },
    [state.values]
  );

  const handleReset = useCallback(() =&gt; {
    dispatch({ type: ACTIONS.RESET });
  }, []);

  // Derived values — computed, not stored in state
  const isFormDirty = Object.values(state.values).some((v) =&gt; v !== '');
  const hasVisibleErrors = Object.entries(state.errors).some(
    ([field, msg]) =&gt; msg &amp;&amp; state.touched[field]
  );

  return {
    values: state.values,
    errors: state.errors,
    touched: state.touched,
    isSubmitting: state.isSubmitting,
    submitStatus: state.submitStatus,
    isFormDirty,
    hasVisibleErrors,
    handleChange,
    handleBlur,
    handleSubmit,
    handleReset,
  };
}
</code></pre>
<p><code>isFormDirty</code> and <code>hasVisibleErrors</code> are derived values — computed on every render from existing state. Never put derived values into state itself; that's how you get stale data. The only things that belong in state are values that <em><mark class="bg-yellow-200 dark:bg-yellow-500/30">can't</mark></em> <mark class="bg-yellow-200 dark:bg-yellow-500/30"> be calculated</mark> — raw user input, server responses, async flags like <code>isSubmitting</code>. Everything else is fair game to derive.</p>
<hr />
<h2>The Component</h2>
<p>With the hook doing all the heavy lifting, the component becomes almost entirely declarative.</p>
<pre><code class="language-jsx">function FieldError({ message, touched }) {
  if (!touched || !message) return null;
  return (
    &lt;span role="alert" style={{ color: 'var(--color-text-danger)', fontSize: 13 }}&gt;
      {message}
    &lt;/span&gt;
  );
}

export default function SignupForm() {
  const {
    values,
    errors,
    touched,
    isSubmitting,
    submitStatus,
    isFormDirty,
    handleChange,
    handleBlur,
    handleSubmit,
    handleReset,
  } = useSignupForm();

  return (
    &lt;form onSubmit={handleSubmit} noValidate&gt;
      &lt;div&gt;
        &lt;label htmlFor="name"&gt;Full name&lt;/label&gt;
        &lt;input
          id="name"
          type="text"
          value={values.name}
          onChange={(e) =&gt; handleChange('name', e.target.value)}
          onBlur={() =&gt; handleBlur('name')}
          disabled={isSubmitting}
          aria-invalid={touched.name &amp;&amp; !!errors.name}
          aria-describedby={errors.name ? 'name-error' : undefined}
        /&gt;
        &lt;FieldError message={errors.name} touched={touched.name} /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label htmlFor="email"&gt;Email&lt;/label&gt;
        &lt;input
          id="email"
          type="email"
          value={values.email}
          onChange={(e) =&gt; handleChange('email', e.target.value)}
          onBlur={() =&gt; handleBlur('email')}
          disabled={isSubmitting}
          aria-invalid={touched.email &amp;&amp; !!errors.email}
        /&gt;
        &lt;FieldError message={errors.email} touched={touched.email} /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label htmlFor="password"&gt;Password&lt;/label&gt;
        &lt;input
          id="password"
          type="password"
          value={values.password}
          onChange={(e) =&gt; handleChange('password', e.target.value)}
          onBlur={() =&gt; handleBlur('password')}
          disabled={isSubmitting}
          aria-invalid={touched.password &amp;&amp; !!errors.password}
        /&gt;
        &lt;FieldError message={errors.password} touched={touched.password} /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label htmlFor="confirmPassword"&gt;Confirm password&lt;/label&gt;
        &lt;input
          id="confirmPassword"
          type="password"
          value={values.confirmPassword}
          onChange={(e) =&gt; handleChange('confirmPassword', e.target.value)}
          onBlur={() =&gt; handleBlur('confirmPassword')}
          disabled={isSubmitting}
          aria-invalid={touched.confirmPassword &amp;&amp; !!errors.confirmPassword}
        /&gt;
        &lt;FieldError message={errors.confirmPassword} touched={touched.confirmPassword} /&gt;
      &lt;/div&gt;

      {submitStatus === 'success' &amp;&amp; (
        &lt;p role="status" style={{ color: 'var(--color-text-success)' }}&gt;
          Account created successfully!
        &lt;/p&gt;
      )}

      {submitStatus === 'error' &amp;&amp; (
        &lt;p role="alert" style={{ color: 'var(--color-text-danger)' }}&gt;
          Something went wrong. Please try again.
        &lt;/p&gt;
      )}

      &lt;button type="submit" disabled={isSubmitting}&gt;
        {isSubmitting ? 'Creating account…' : 'Create account'}
      &lt;/button&gt;

      {isFormDirty &amp;&amp; (
        &lt;button type="button" onClick={handleReset} disabled={isSubmitting}&gt;
          Clear form
        &lt;/button&gt;
      )}
    &lt;/form&gt;
  );
}
</code></pre>
<p>The component contains zero business logic. It maps state to UI, and UI events to handlers. That's its entire job.</p>
<hr />
<h2>The State Machine, Visualised</h2>
<p>Here's how the form moves through its lifecycle:Every box here corresponds to a distinct shape of your state object. The reducer enforces that you can only move along the valid arrows — there's no code path that accidentally leaves <code>isSubmitting: true</code> when an error happens.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/4ef0dd29-633f-4cc1-a7b9-d4a4320c576b.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>Production Patterns Worth Noting</h2>
<p><strong>Why</strong> <code>useCallback</code> <strong>on every handler?</strong></p>
<p>The custom hook returns new function references on every render by default. If you pass <code>handleChange</code> as a prop to a child field component wrapped in <code>React.memo</code>, a new reference breaks memoisation. <code>useCallback</code> with accurate dependency arrays prevents that.</p>
<p><strong>Why clear errors on</strong> <code>SET_FIELD</code><strong>?</strong></p>
<p>The UX expectation is "error disappears the moment you start fixing it." If you only clear on re-blur, the user sees the error while they're typing the correction — that's friction with no payoff.</p>
<p><strong>Why not store derived values in state?</strong></p>
<p><code>isFormDirty</code> is always computable from <code>values</code>. If you stored it separately, you'd need to remember to update it every time <code>SET_FIELD</code> fires. That's a coordination bug waiting to happen. Compute it, don't store it.</p>
<p><strong>Why batch all touches on failed submit?</strong></p>
<p>When a user clicks submit without touching any field, no errors are visible yet (because no field is <code>touched</code>). The submit handler marks all fields as touched at once, so every unfilled field suddenly shows its error. This is the standard behaviour users expect from production forms.</p>
<p><strong>Why does</strong> <code>SUBMIT_SUCCESS</code> <strong>return</strong> <code>{ ...initialState, submitStatus: 'success' }</code><strong>?</strong></p>
<p>If you returned <code>initialState</code> directly, <code>submitStatus</code> would be <code>null</code> and you'd have no way to show a success message. Spreading <code>initialState</code> and then overriding one key is the clean pattern.</p>
<hr />
<h2>Fake API for Testing</h2>
<p>Here's a simple async stub you can swap out for a real call:</p>
<pre><code class="language-js">async function fakeApiCall(values) {
  await new Promise((res) =&gt; setTimeout(res, 1500));

  // Simulate a server-side email-taken error
  if (values.email === 'taken@example.com') {
    const err = new Error('Email already registered');
    err.fieldErrors = { email: 'This email is already in use.' };
    throw err;
  }
}
</code></pre>
<p>Notice <code>err.fieldErrors</code> — the reducer's <code>SUBMIT_FAILURE</code> case reads <code>action.errors</code> and spreads it into <code>state.errors</code>, so server-side field errors land in exactly the right place and show up under the right input.</p>
<hr />
<h2>What This Buys You</h2>
<p>The architecture you now have is testable in complete isolation — you can import <code>formReducer</code> and <code>validate</code> and unit-test every transition without mounting a single component. The component itself is a thin presentation layer. The custom hook is the interface. The reducer is the contract.</p>
<p>When requirements change — add a <code>username</code> field, add async email-availability checks, add a progress stepper — you add to the state shape, add an action, and update the reducer. Nothing else needs to change.</p>
]]></content:encoded></item><item><title><![CDATA[useReducer in React: A Simple Counter, Then the Bigger Picture]]></title><description><![CDATA[Why Does useReducer Even Exist?
Before writing a single line of code, let's build the right mental model.
You already know useState. It's clean, it's simple, and it works great when a piece of state i]]></description><link>https://yashrajxdev.blog/usereducer-in-react-a-simple-counter-then-the-bigger-picture</link><guid isPermaLink="true">https://yashrajxdev.blog/usereducer-in-react-a-simple-counter-then-the-bigger-picture</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[claude.ai]]></category><category><![CDATA[gemini]]></category><category><![CDATA[#anthropic]]></category><category><![CDATA[Google Antigravity]]></category><category><![CDATA[google-stitch ]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 21 Mar 2026 08:06:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/60f41aff-ce04-42b3-9037-8b506d24297e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Why Does <code>useReducer</code> Even Exist?</h2>
<p>Before writing a single line of code, let's build the right mental model.</p>
<p>You already know <code>useState</code>. It's clean, it's simple, and it works great when a piece of state is self-contained — like a toggle, a string input, or a counter. But as your component grows, you'll notice something uncomfortable: the <em>logic</em> for how state changes starts spreading everywhere. One button calls <code>setCount(count + 1)</code>, another calls <code>setCount(0)</code>, another calls <code>setCount(count - 1)</code>, and suddenly your JSX is littered with little inline decisions about <em>how</em> state should change.</p>
<p><code>useReducer</code> says: <em><mark class="bg-yellow-200 dark:bg-yellow-500/30">what if all those decisions lived in one place?</mark></em></p>
<p>That one place is called a <strong>reducer</strong> — a pure function (returns same results with same set of inputs) that takes your current state and an action, and returns the new state. That's the whole pattern. Everything else is just details.</p>
<hr />
<h2>The Counter Example</h2>
<p>Let's start with the simplest possible example: a counter with increment, decrement, and reset.</p>
<h3>Step 1: Define Your State and Actions</h3>
<p>First, think about what your state looks like and what can happen to it. For a counter, the state is just a number. The things that can happen are: go up, go down, reset.</p>
<pre><code class="language-javascript">// This is what our state looks like
const initialState = { count: 0 };

// These are the "things that can happen" — we call them actions.
// Each action is just a plain object with a 'type' field.
// { type: 'INCREMENT' }
// { type: 'DECREMENT' }
// { type: 'RESET' }
</code></pre>
<h3>Step 2: Write the Reducer</h3>
<p>The reducer is a function with a simple contract: given the <em>current state</em> and an <em>action</em>, return the <em>next state</em>. <mark class="bg-yellow-200 dark:bg-yellow-500/30">It never mutates — it always returns a fresh value.</mark></p>
<pre><code class="language-js">function counterReducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };

    case 'DECREMENT':
      return { count: state.count - 1 };

    case 'RESET':
      return { count: 0 };

    default:
      // If we receive an unknown action, return state unchanged.
      // This is a safety net — never throw away state accidentally.
      return state;
  }
}
</code></pre>
<p>Notice what's happening here: the reducer is a <em>map</em> from (state, action) → new state. It has no side effects. It doesn't call any APIs, doesn't touch the DOM, and doesn't depend on anything outside its arguments. This purity is what makes reducers so predictable and easy to test.</p>
<h3>Step 3: Wire It Into the Component</h3>
<p>Now you use <code>useReducer(reducer, initialState)</code>. It hands you back two things — the current state, and a <code>dispatch</code> function. When you call <code>dispatch({ type: 'INCREMENT' })</code>, React runs your reducer with that action and re-renders the component with the new state.</p>
<pre><code class="language-jsx">import { useReducer } from 'react';

function counterReducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    case 'RESET':
      return { count: 0 };
    default:
      return state;
  }
}

const initialState = { count: 0 };

export default function Counter() {
  // useReducer returns [currentState, dispatchFunction]
  const [state, dispatch] = useReducer(counterReducer, initialState);

  return (
    &lt;div&gt;
      &lt;h2&gt;Count: {state.count}&lt;/h2&gt;

      {/* Each button just dispatches an action — it doesn't know HOW state changes */}
      &lt;button onClick={() =&gt; dispatch({ type: 'INCREMENT' })}&gt;+&lt;/button&gt;
      &lt;button onClick={() =&gt; dispatch({ type: 'DECREMENT' })}&gt;−&lt;/button&gt;
      &lt;button onClick={() =&gt; dispatch({ type: 'RESET' })}&gt;Reset&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>Take a moment to notice how the JSX is now clean. The buttons don't contain logic — they just declare <em>intent</em>. "I want to increment." The reducer decides what that means.</p>
<hr />
<h2>The Key Mental Shift: Events vs. Mutations</h2>
<p>Here's the most important idea behind the reducer pattern, and it's worth sitting with.</p>
<p>With <code>useState</code>, you think like this: <em>"When this button is clicked, set the count to count + 1."</em> You're thinking about <strong>mutations</strong> — directly manipulating the value.</p>
<p>With <code>useReducer</code>, you think like this: <em>"When this button is clicked, something happened — an INCREMENT event occurred."</em> You're thinking about <strong>events</strong> (or actions), and you're letting the reducer decide what the state should look like in response to that event.</p>
<p>This is the same shift that makes Redux, Flux, and even event-sourced databases so powerful. Your component becomes a <em>sender of events</em>, not a <em>manager of state</em>. The reducer owns all the logic.</p>
<hr />
<h2>Actions with Payloads</h2>
<p>Real-world actions often carry data. Suppose you want an "add by N" button. You'd pass the number as a payload inside the action object:</p>
<pre><code class="language-js">// Dispatching an action with a payload
dispatch({ type: 'ADD_BY', payload: 5 });

// And in the reducer...
case 'ADD_BY':
  return { count: state.count + action.payload };
</code></pre>
<p>The convention is to use <code>type</code> for the action name and <code>payload</code> for the data it carries. This isn't enforced by React — it's just a widely adopted community pattern that keeps things readable.</p>
<hr />
<h2>When to Prefer <code>useReducer</code> Over <code>useState</code></h2>
<p>The React docs themselves give a clear rule of thumb here, and it maps well to real experience.</p>
<p>Reach for <code>useReducer</code> when your state has <strong>multiple sub-values</strong> that change together (like a form with name, email, and password), when <strong>the next state depends on the previous state</strong> in complex ways, or when you have <strong>many different ways to update state</strong> and the component is getting hard to read. If you ever find yourself writing three or four <code>setState</code> calls in a single event handler to keep things in sync, that's a strong signal to consolidate into a reducer.</p>
<p>On the other hand, <code>useState</code> remains the right tool for simple, isolated values. A modal's <code>isOpen</code> flag doesn't need a reducer. A single text input doesn't need a reducer. Match the tool to the complexity.</p>
<hr />
<h2>A Slightly Richer Example: Form State</h2>
<p>To cement the idea, here's how the same reducer pattern scales gracefully to a login form — the kind of thing that would get messy fast with three separate <code>useState</code> calls.</p>
<pre><code class="language-jsx">const initialState = {
  username: '',
  password: '',
  isSubmitting: false,
};

function formReducer(state, action) {
  switch (action.type) {
    case 'SET_FIELD':
      // action.payload = { field: 'username', value: 'yashraj' }
      return { ...state, [action.payload.field]: action.payload.value };

    case 'SUBMIT_START':
      return { ...state, isSubmitting: true };

    case 'SUBMIT_DONE':
      return { ...state, isSubmitting: false };

    default:
      return state;
  }
}

function LoginForm() {
  const [state, dispatch] = useReducer(formReducer, initialState);

  const handleChange = (e) =&gt; {
    dispatch({
      type: 'SET_FIELD',
      payload: { field: e.target.name, value: e.target.value },
    });
  };

  const handleSubmit = async () =&gt; {
    dispatch({ type: 'SUBMIT_START' });
    await fakeApiCall(state);
    dispatch({ type: 'SUBMIT_DONE' });
  };

  return (
    &lt;div&gt;
      &lt;input name="username" value={state.username} onChange={handleChange} /&gt;
      &lt;input name="password" type="password" value={state.password} onChange={handleChange} /&gt;
      &lt;button onClick={handleSubmit} disabled={state.isSubmitting}&gt;
        {state.isSubmitting ? 'Logging in...' : 'Login'}
      &lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>Notice that <code>SET_FIELD</code> handles <em>all</em> fields with a single case — because the field name is part of the payload. All three fields stay in one state object, transitions are all visible in one reducer, and the component is left responsible only for rendering and dispatching.</p>
<hr />
<h2>The Bigger Picture: Where This Pattern Lives</h2>
<p><code>useReducer</code> is React's take on a much older idea. The reducer pattern is borrowed from functional programming — specifically from the <code>Array.prototype.reduce</code> idea that you fold a list of changes into a final value. Redux, which became enormously popular in the React ecosystem, is essentially this pattern at the application level.</p>
<p>Understanding <code>useReducer</code> well also makes the leap to Redux Context patterns, Zustand, and other state libraries much easier — because they all share this same vocabulary of <em>actions</em>, <em>reducers</em>, and <em>dispatch</em>.</p>
<hr />
<h2>Notes</h2>
<p>The reducer pattern is fundamentally about <strong>separating what happened from what it means</strong>. Your UI dispatches events. Your reducer decides what those events mean for state. That separation keeps your components clean, your logic testable, and your state transitions auditable — you can read the reducer top to bottom and know every possible way your state can change.</p>
<p>Start with the counter. Internalize the <code>(state, action) =&gt; newState</code> contract. Then notice how naturally it scales when your state grows more complex. That's the pattern working as designed.</p>
]]></content:encoded></item><item><title><![CDATA[useContext in Action: Consuming Context Like a Pro - React Guide]]></title><description><![CDATA[If you've read the previous article, you know what useContext is and how the Context API works under the hood. You've seen createContext, Provider, and the basic useContext call. Good. Now let's throw]]></description><link>https://yashrajxdev.blog/usecontext-in-action-consuming-context-like-a-pro-react-guide</link><guid isPermaLink="true">https://yashrajxdev.blog/usecontext-in-action-consuming-context-like-a-pro-react-guide</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sun, 15 Mar 2026 11:44:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/6c28f24e-99e6-476d-9b6d-7db5c55e206e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've read the <a href="http://yashrajxdev.blog/react-usecontext-hook-definition-use-cases-performance-tips">previous article</a>, you know what <code>useContext</code> is and how the Context API works under the hood. You've seen <code>createContext</code>, <code>Provider</code>, and the basic <code>useContext</code> call. Good. Now let's throw away the toy examples.</p>
<p>This article is about <strong>how experienced React engineers actually use</strong> <code>useContext</code> — the patterns that show up in real codebases, the mistakes that silently destroy performance, and the architectural decisions that make context scale without becoming a liability.</p>
<hr />
<h2>A Quick Reset: What You Already Know</h2>
<pre><code class="language-javascript">const ThemeContext = createContext('light');

function App() {
  return (
    &lt;ThemeContext.Provider value="dark"&gt;
      &lt;Page /&gt;
    &lt;/ThemeContext.Provider&gt;
  );
}

function Page() {
  const theme = useContext(ThemeContext);
  return &lt;div className={theme}&gt;Hello&lt;/div&gt;;
}
</code></pre>
<p>This works. But in production, you'll almost never write context this raw. Let's build up from here.</p>
<hr />
<h2>Pattern 1: The Custom Hook Wrapper (The Standard)</h2>
<p>Exposing the raw context object to consumers is a footgun. If someone calls <code>useContext(ThemeContext)</code> outside of a Provider, they get the default value silently — no error, no warning, just a bug that's hard to trace.</p>
<p>The fix is to wrap <code>useContext</code> in a custom hook that validates its environment:</p>
<pre><code class="language-javascript">// context/ThemeContext.js
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  const toggle = () =&gt;
    setTheme(prev =&gt; (prev === 'light' ? 'dark' : 'light'));

  return (
    &lt;ThemeContext.Provider value={{ theme, toggle }}&gt;
      {children}
    &lt;/ThemeContext.Provider&gt;
  );
}

export function useTheme() {
  const context = useContext(ThemeContext);
  if (context === null) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
}
</code></pre>
<p>Now consumers do this:</p>
<pre><code class="language-jsx">import { useTheme } from '@/context/ThemeContext';

function Navbar() {
  const { theme, toggle } = useTheme();
  return (
    &lt;nav className={`navbar navbar--${theme}`}&gt;
      &lt;button onClick={toggle}&gt;Switch to {theme === 'light' ? 'dark' : 'light'} mode&lt;/button&gt;
    &lt;/nav&gt;
  );
}
</code></pre>
<p><strong>Why this matters:</strong></p>
<ul>
<li><p>The error boundary is clear and immediate — you know exactly where the context is missing.</p>
</li>
<li><p>Consumers never import the raw context object. They only import <code>useTheme</code>. This means you can completely refactor the internals later without touching a single consumer.</p>
</li>
<li><p>It reads like domain language, not React plumbing.</p>
</li>
</ul>
<hr />
<h2>Pattern 2: Auth Context — The Most Common Production Use Case</h2>
<p>Authentication state is the canonical use case for context. It's global, it changes infrequently, and nearly every component in the app needs to <em>read</em> it (but rarely write it).</p>
<pre><code class="language-jsx">// context/AuthContext.js
import { createContext, useContext, useState, useEffect } from 'react';

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() =&gt; {
    // Simulate token check on mount
    const storedUser = localStorage.getItem('user');
    if (storedUser) {
      setUser(JSON.parse(storedUser));
    }
    setLoading(false);
  }, []);

  const login = async (credentials) =&gt; {
    const response = await fakeAuthAPI(credentials);
    setUser(response.user);
    localStorage.setItem('user', JSON.stringify(response.user));
  };

  const logout = () =&gt; {
    setUser(null);
    localStorage.removeItem('user');
  };

  return (
    &lt;AuthContext.Provider value={{ user, loading, login, logout }}&gt;
      {children}
    &lt;/AuthContext.Provider&gt;
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) throw new Error('useAuth must be used within AuthProvider');
  return context;
}
</code></pre>
<p>Now your protected routes become trivial to write:</p>
<pre><code class="language-jsx">function ProtectedRoute({ children }) {
  const { user, loading } = useAuth();

  if (loading) return &lt;Spinner /&gt;;
  if (!user) return &lt;Navigate to="/login" /&gt;;
  return children;
}
</code></pre>
<p>And your login button anywhere in the tree:</p>
<pre><code class="language-jsx">function Header() {
  const { user, logout } = useAuth();

  return (
    &lt;header&gt;
      {user ? (
        &lt;&gt;
          &lt;span&gt;Welcome, {user.name}&lt;/span&gt;
          &lt;button onClick={logout}&gt;Sign out&lt;/button&gt;
        &lt;/&gt;
      ) : (
        &lt;a href="/login"&gt;Sign in&lt;/a&gt;
      )}
    &lt;/header&gt;
  );
}
</code></pre>
<p>No props. No drilling through <code>App → Layout → Header</code>. Clean.</p>
<hr />
<h2>Pattern 3: Splitting Context to Avoid Unnecessary Re-renders</h2>
<p>Here's a performance trap most React developers hit once and never forget.</p>
<p>Imagine you have a shopping cart context:</p>
<pre><code class="language-jsx">// ❌ The naive version
const CartContext = createContext(null);

export function CartProvider({ children }) {
  const [items, setItems] = useState([]);
  const [isOpen, setIsOpen] = useState(false);

  const addItem = (item) =&gt; setItems(prev =&gt; [...prev, item]);
  const removeItem = (id) =&gt; setItems(prev =&gt; prev.filter(i =&gt; i.id !== id));
  const toggle = () =&gt; setIsOpen(prev =&gt; !prev);

  return (
    &lt;CartContext.Provider value={{ items, isOpen, addItem, removeItem, toggle }}&gt;
      {children}
    &lt;/CartContext.Provider&gt;
  );
}
</code></pre>
<p>Every time <code>isOpen</code> toggles (like when the cart drawer opens), <strong>every component consuming this context re-renders</strong> — including your product cards that only care about <code>addItem</code>. This is wasteful and gets expensive at scale.</p>
<p>The fix: split your context by update frequency and concern.</p>
<pre><code class="language-jsx">// ✅ Split context
const CartStateContext = createContext(null);
const CartActionsContext = createContext(null);
const CartUIContext = createContext(null);

export function CartProvider({ children }) {
  const [items, setItems] = useState([]);
  const [isOpen, setIsOpen] = useState(false);

  // Memoize actions so their references stay stable
  const actions = useMemo(() =&gt; ({
    addItem: (item) =&gt; setItems(prev =&gt; [...prev, item]),
    removeItem: (id) =&gt; setItems(prev =&gt; prev.filter(i =&gt; i.id !== id)),
  }), []);

  const ui = useMemo(() =&gt; ({
    isOpen,
    toggle: () =&gt; setIsOpen(prev =&gt; !prev),
  }), [isOpen]);

  return (
    &lt;CartActionsContext.Provider value={actions}&gt;
      &lt;CartUIContext.Provider value={ui}&gt;
        &lt;CartStateContext.Provider value={items}&gt;
          {children}
        &lt;/CartStateContext.Provider&gt;
      &lt;/CartUIContext.Provider&gt;
    &lt;/CartActionsContext.Provider&gt;
  );
}

// Each hook only subscribes to what it needs
export const useCartItems = () =&gt; useContext(CartStateContext);
export const useCartActions = () =&gt; useContext(CartActionsContext);
export const useCartUI = () =&gt; useContext(CartUIContext);
</code></pre>
<p>Now a product card that just needs <code>addItem</code> consumes <code>useCartActions</code> — it will <strong>never re-render</strong> when the cart drawer opens or closes.</p>
<hr />
<h2>Pattern 4: Multi-Level Context (Scope-Aware Providers)</h2>
<p>Context isn't just for global, app-wide state. You can scope it to a subtree — and this is an underused, powerful pattern.</p>
<p>Imagine a <code>DataGrid</code> component. Each row needs to know its own row data and whether it's selected. You don't want this to live in global state. Instead, create row-scoped context:</p>
<pre><code class="language-jsx">const RowContext = createContext(null);

function DataGrid({ rows }) {
  return (
    &lt;table&gt;
      &lt;tbody&gt;
        {rows.map(row =&gt; (
          &lt;RowContext.Provider key={row.id} value={row}&gt;
            &lt;TableRow /&gt;
          &lt;/RowContext.Provider&gt;
        ))}
      &lt;/tbody&gt;
    &lt;/table&gt;
  );
}

function TableRow() {
  const row = useContext(RowContext);
  return (
    &lt;tr&gt;
      &lt;td&gt;{row.name}&lt;/td&gt;
      &lt;td&gt;{row.status}&lt;/td&gt;
      &lt;ActionCell /&gt;
    &lt;/tr&gt;
  );
}

function ActionCell() {
  const row = useContext(RowContext); // Gets the nearest Provider's value
  return &lt;button onClick={() =&gt; handleAction(row.id)}&gt;Edit&lt;/button&gt;;
}
</code></pre>
<p>Each <code>&lt;RowContext.Provider&gt;</code> wraps its own row. Any component inside that row can reach up and grab that row's data without knowing where it lives in the component tree. This is the same mechanism that makes compound component patterns like <code>&lt;Select&gt;</code> / <code>&lt;Option&gt;</code> work in UI libraries.</p>
<hr />
<h2>Pattern 5: Context + useReducer (The Flux-Lite Pattern)</h2>
<p>When your context state has multiple related fields and complex transitions, <code>useState</code> gets messy. <code>useReducer</code> pairs naturally with context to give you Redux-like clarity without the Redux overhead.</p>
<pre><code class="language-jsx">const initialState = {
  theme: 'light',
  language: 'en',
  notifications: true,
};

function settingsReducer(state, action) {
  switch (action.type) {
    case 'SET_THEME':
      return { ...state, theme: action.payload };
    case 'SET_LANGUAGE':
      return { ...state, language: action.payload };
    case 'TOGGLE_NOTIFICATIONS':
      return { ...state, notifications: !state.notifications };
    case 'RESET':
      return initialState;
    default:
      throw new Error(`Unknown action: ${action.type}`);
  }
}

const SettingsContext = createContext(null);

export function SettingsProvider({ children }) {
  const [settings, dispatch] = useReducer(settingsReducer, initialState);

  return (
    &lt;SettingsContext.Provider value={{ settings, dispatch }}&gt;
      {children}
    &lt;/SettingsContext.Provider&gt;
  );
}

export function useSettings() {
  const ctx = useContext(SettingsContext);
  if (!ctx) throw new Error('useSettings must be used within SettingsProvider');
  return ctx;
}
</code></pre>
<p>Consumer usage is clear and intention-revealing:</p>
<pre><code class="language-jsx">function SettingsPanel() {
  const { settings, dispatch } = useSettings();

  return (
    &lt;div&gt;
      &lt;select
        value={settings.theme}
        onChange={e =&gt; dispatch({ type: 'SET_THEME', payload: e.target.value })}
      &gt;
        &lt;option value="light"&gt;Light&lt;/option&gt;
        &lt;option value="dark"&gt;Dark&lt;/option&gt;
      &lt;/select&gt;

      &lt;button onClick={() =&gt; dispatch({ type: 'TOGGLE_NOTIFICATIONS' })}&gt;
        Notifications: {settings.notifications ? 'On' : 'Off'}
      &lt;/button&gt;

      &lt;button onClick={() =&gt; dispatch({ type: 'RESET' })}&gt;
        Reset to defaults
      &lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>The reducer acts as a single source of truth for all state transitions. Each dispatch call is an explicit, named event — easy to trace, easy to test.</p>
<hr />
<h2>The Performance Reality Check</h2>
<p><code>useContext</code> does <strong>not</strong> bail out of re-renders. Unlike <code>useState</code> which skips re-renders when the value doesn't change, every context consumer re-renders whenever the Provider's <code>value</code> prop changes — even if the part of the value they use is the same.</p>
<p>The most common mistake is creating a new object reference on every render:</p>
<pre><code class="language-jsx">// ❌ New object on every render = every consumer re-renders every time
&lt;AuthContext.Provider value={{ user, login, logout }}&gt;
</code></pre>
<p>Fix it with <code>useMemo</code>:</p>
<pre><code class="language-jsx">// ✅ Stable reference unless user, login, or logout change
const value = useMemo(() =&gt; ({ user, login, logout }), [user, login, logout]);
&lt;AuthContext.Provider value={value}&gt;
</code></pre>
<p>For functions specifically, use <code>useCallback</code>:</p>
<pre><code class="language-jsx">const login = useCallback(async (credentials) =&gt; {
  const res = await authAPI(credentials);
  setUser(res.user);
}, []); // No deps — this never needs to change
</code></pre>
<hr />
<h2>When to Reach for Zustand or Redux Instead</h2>
<p>Context is not a state management library. It's a dependency injection mechanism. The distinction matters:</p>
<table>
<thead>
<tr>
<th>Scenario</th>
<th>Use Context</th>
<th>Use Zustand/Redux</th>
</tr>
</thead>
<tbody><tr>
<td>Auth state</td>
<td>✅</td>
<td>Overkill</td>
</tr>
<tr>
<td>Theme / locale</td>
<td>✅</td>
<td>Overkill</td>
</tr>
<tr>
<td>High-frequency updates (mouse pos, scroll)</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td>Large, normalized server state</td>
<td>❌</td>
<td>✅ (or React Query)</td>
</tr>
<tr>
<td>Deeply nested, frequently-mutated UI state</td>
<td>⚠️ Profile first</td>
<td>✅</td>
</tr>
<tr>
<td>Sharing state between unrelated subtrees</td>
<td>✅</td>
<td>✅</td>
</tr>
</tbody></table>
<p>Context re-renders all consumers on value change. This is fine when the data changes rarely (theme, auth, settings). It becomes a problem when dat a updates multiple times per second or when thousands of components are subscribed.</p>
<hr />
<h2>Putting It Together: A Real Feature</h2>
<p>Here's what a complete, <mark class="bg-yellow-200 dark:bg-yellow-500/30">production-ready notification system</mark> looks like using everything above:</p>
<pre><code class="language-jsx">// context/NotificationContext.js
import { createContext, useContext, useReducer, useCallback } from 'react';

const NotificationContext = createContext(null);

function notificationReducer(state, action) {
  switch (action.type) {
    case 'ADD':
      return [...state, { id: Date.now(), ...action.payload }];
    case 'REMOVE':
      return state.filter(n =&gt; n.id !== action.id);
    case 'CLEAR':
      return [];
    default:
      return state;
  }
}

export function NotificationProvider({ children }) {
  const [notifications, dispatch] = useReducer(notificationReducer, []);

  const notify = useCallback((message, type = 'info') =&gt; {
    const id = Date.now();
    dispatch({ type: 'ADD', payload: { message, type } });

    // Auto-dismiss after 4s
    setTimeout(() =&gt; dispatch({ type: 'REMOVE', id }), 4000);
  }, []);

  const dismiss = useCallback((id) =&gt; {
    dispatch({ type: 'REMOVE', id });
  }, []);

  return (
    &lt;NotificationContext.Provider value={{ notifications, notify, dismiss }}&gt;
      {children}
      &lt;NotificationToast /&gt;
    &lt;/NotificationContext.Provider&gt;
  );
}

export function useNotification() {
  const ctx = useContext(NotificationContext);
  if (!ctx) throw new Error('useNotification must be used within NotificationProvider');
  return ctx;
}

// The UI layer lives inside the Provider itself
function NotificationToast() {
  const { notifications, dismiss } = useContext(NotificationContext);

  return (
    &lt;div className="toast-container"&gt;
      {notifications.map(n =&gt; (
        &lt;div key={n.id} className={`toast toast--${n.type}`}&gt;
          &lt;span&gt;{n.message}&lt;/span&gt;
          &lt;button onClick={() =&gt; dismiss(n.id)}&gt;×&lt;/button&gt;
        &lt;/div&gt;
      ))}
    &lt;/div&gt;
  );
}
</code></pre>
<p>Anywhere in your app:</p>
<pre><code class="language-jsx">function SaveButton() {
  const { notify } = useNotification();

  const handleSave = async () =&gt; {
    try {
      await saveData();
      notify('Changes saved successfully', 'success');
    } catch {
      notify('Failed to save. Please try again.', 'error');
    }
  };

  return &lt;button onClick={handleSave}&gt;Save&lt;/button&gt;;
}
</code></pre>
<p>No prop threading. No event emitters. No external libraries. Just context doing exactly what it was built for.</p>
<hr />
<h2>Key Takeaways</h2>
<ul>
<li><p><strong>Always wrap</strong> <code>useContext</code> <strong>in a custom hook.</strong> It enforces provider boundaries, hides implementation details, and reads like your domain.</p>
</li>
<li><p><strong>Split contexts by concern.</strong> State, actions, and UI state often belong in separate contexts when they update at different frequencies.</p>
</li>
<li><p><strong>Memoize your context value.</strong> <mark class="bg-yellow-200 dark:bg-yellow-500/30">An inline object literal creates a new reference on every render. </mark> <code>useMemo</code> <mark class="bg-yellow-200 dark:bg-yellow-500/30"> stops that.</mark></p>
</li>
<li><p><strong>Pair</strong> <code>useReducer</code> <strong>with context</strong> when state has complex transitions or more than two or three related fields.</p>
</li>
<li><p><strong>Scope context to subtrees</strong>, not just the app root — it's a powerful pattern for compound components and reusable feature modules.</p>
</li>
<li><p><strong>Know when to stop.</strong> Context is a delivery mechanism, not a substitute for Zustand, Redux, or React Query when you're dealing with high-frequency or server-synchronized state.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[React useContext Hook: Definition, Use Cases & Performance Tips]]></title><description><![CDATA[1. What is useContext?
Simply put, useContext is a built-in React hook that lets any component read shared data directly — without needing someone to pass it down through props.
useContext is a React ]]></description><link>https://yashrajxdev.blog/react-usecontext-hook-definition-use-cases-performance-tips</link><guid isPermaLink="true">https://yashrajxdev.blog/react-usecontext-hook-definition-use-cases-performance-tips</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Thu, 12 Mar 2026 18:13:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/0ca1bbaa-13f0-4036-a86b-57594409e5e3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1. What is useContext?</h2>
<p>Simply put, <code>useContext</code> is a built-in React hook that lets any component read shared data directly — without needing someone to pass it down through props.</p>
<p><code>useContext</code> is a React Hook that lets you read and subscribe to context from your component.</p>
<p>Think of it like a <strong>group chat</strong>. Instead of one person forwarding a message to the next person, who forwards it to the next — you just broadcast it to the whole group and anyone who needs it can read it.</p>
<p>Here's the signature. It really is this simple:</p>
<pre><code class="language-js">const value = useContext(MyContext);
</code></pre>
<p>Internally, <code>useContext</code> is built on top of React’s <strong>Context API</strong> — a feature designed to share data across a component tree without manually passing props at every level. It is commonly used for values that are needed globally in the app, such as the current user, theme, or language.</p>
<hr />
<h2>2. Why Do We Need It? (The Prop Drilling Problem)</h2>
<p>To understand the benefit, first imagine the problem.</p>
<p>Suppose your app needs to show the logged-in user’s name in multiple places like the Navbar, Sidebar, Profile page, and a deeply nested Settings panel. Without context, you would need to pass the <code>user</code> prop through every component in the hierarchy — even through components that don’t actually use it.</p>
<p>This situation is known as <strong>prop drilling</strong>.</p>
<p>Example structure:</p>
<pre><code class="language-plaintext">App (contains user data)
  └── Layout (passes user prop)
        └── Sidebar (passes user prop)
              └── Panel (passes user prop)
                    └── UserCard ← finally uses the user data
</code></pre>
<p>Layout, Sidebar, and Panel don't need <code>user</code> at all. They're just acting as middlemen. This makes your code:</p>
<ul>
<li><p><strong>Hard to read</strong> — component signatures get bloated with props they don't use</p>
</li>
<li><p><strong>Hard to refactor</strong> — rename a prop and you're updating five files</p>
</li>
<li><p><strong>Fragile</strong> — add a new layer and you need to thread the prop through again</p>
</li>
</ul>
<p>useContext solves this cleanly. You broadcast the value from the top, and <code>UserCard</code> subscribes directly — all the middle components stay completely unaware.</p>
<hr />
<h2>3. How It Works: The 3-Step Pattern</h2>
<p>Using useContext always follows the same three steps.</p>
<p><strong>Step 1 — Create the context</strong></p>
<pre><code class="language-javascript">// ThemeContext.js
import { createContext } from 'react';

// The argument is the default value (used when no Provider is found above)
export const ThemeContext = createContext('light');
</code></pre>
<p><strong>Step 2 — Wrap your component tree with a Provider</strong></p>
<pre><code class="language-javascript">// App.jsx
import { useState } from 'react';
import { ThemeContext } from './ThemeContext';

export default function App() {
  const [theme, setTheme] = useState('light');

  return (
    // Every child inside this Provider can read "theme"
    &lt;ThemeContext.Provider value={theme}&gt;
      &lt;Navbar /&gt;
      &lt;MainContent /&gt;
      &lt;button onClick={() =&gt; setTheme(t =&gt; t === 'light' ? 'dark' : 'light')}&gt;
        Toggle Theme
      &lt;/button&gt;
    &lt;/ThemeContext.Provider&gt;
  );
}
</code></pre>
<p><strong>Step 3 — Consume it anywhere with useContext</strong></p>
<pre><code class="language-javascript">// Navbar.jsx
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function Navbar() {
  // No props needed — just read directly
  const theme = useContext(ThemeContext);

  return &lt;nav className={`navbar ${theme}`}&gt;Current theme: {theme}&lt;/nav&gt;;
}
</code></pre>
<p>That's the entire pattern. Create → Provide → Consume.</p>
<hr />
<h2>4. Basic Example: Theme Switcher</h2>
<p>Here's the complete example in one place, copy-paste ready:</p>
<pre><code class="language-javascript">import { createContext, useContext, useState } from 'react';

// 1. Create context
const ThemeContext = createContext('light');

// 2. Custom hook (optional but highly recommended)
function useTheme() {
  return useContext(ThemeContext);
}

// 3. A deeply nested component — zero props needed
function Card() {
  const theme = useTheme();
  const isDark = theme === 'dark';

  return (
    &lt;div style={{
      background: isDark ? '#1e1e3a' : '#ffffff',
      color: isDark ? '#ffffff' : '#1a1a2e',
      padding: '16px',
      borderRadius: '8px'
    }}&gt;
      &lt;p&gt;I'm a card in &lt;strong&gt;{theme}&lt;/strong&gt; mode!&lt;/p&gt;
    &lt;/div&gt;
  );
}

// 4. Root component — provides the value
export default function App() {
  const [theme, setTheme] = useState('light');

  return (
    &lt;ThemeContext.Provider value={theme}&gt;
      &lt;Card /&gt;
      &lt;button onClick={() =&gt; setTheme(t =&gt; t === 'light' ? 'dark' : 'light')}&gt;
        Toggle Theme
      &lt;/button&gt;
    &lt;/ThemeContext.Provider&gt;
  );
}
</code></pre>
<blockquote>
<p><strong>Pro tip:</strong> Notice the <code>useTheme()</code> custom hook. Instead of calling <code>useContext(ThemeContext)</code> in every file, you wrap it once and export a clean, meaningful hook name. This is considered best practice and makes your code easier to test and change later.</p>
</blockquote>
<hr />
<h2>5. Real-World Example: Auth Context</h2>
<p>Authentication is the most common real-world use for context. Here's a production-ready pattern:</p>
<pre><code class="language-javascript">// AuthContext.jsx
import { createContext, useContext, useState, useMemo } from 'react';

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const value = useMemo(() =&gt; ({
    user,
    login: (userData) =&gt; setUser(userData),
    logout: () =&gt; setUser(null),
  }), [user]);

  return (
    &lt;AuthContext.Provider value={value}&gt;
      {children}
    &lt;/AuthContext.Provider&gt;
  );
}

// Custom hook with a helpful error guard
export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used inside &lt;AuthProvider&gt;');
  }
  return context;
}
</code></pre>
<p>Now in any component, anywhere in the app:</p>
<pre><code class="language-javascript">function Dashboard() {
  const { user, logout } = useAuth();

  return (
    &lt;div&gt;
      &lt;h1&gt;Welcome, {user.name}!&lt;/h1&gt;
      &lt;button onClick={logout}&gt;Log out&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>Clean, readable, and no prop chains in sight.</p>
<hr />
<h2>6. Performance Considerations</h2>
<p><strong>The core rule:</strong> Every component that calls <code>useContext</code> will <mark class="bg-yellow-200 dark:bg-yellow-500/30">re-render</mark> whenever the context value changes — even if the specific part it uses hasn't changed.</p>
<h3>The Re-render Trap</h3>
<pre><code class="language-jsx">// ❌ One giant context — a cart update re-renders EVERYONE
&lt;AppContext.Provider value={{ user, theme, cart, settings }}&gt;
  {children}
&lt;/AppContext.Provider&gt;
</code></pre>
<p>If <code>cart</code> updates (say, someone adds an item), every single component consuming <code>AppContext</code> will re-render — including those that only care about <code>theme</code> or <code>user</code>. On a large app, this adds up fast.</p>
<h3>The Fix: Split Contexts by Concern</h3>
<pre><code class="language-jsx">// ✅ Separate contexts — cart updates only affect cart consumers
&lt;ThemeContext.Provider value={theme}&gt;
  &lt;AuthContext.Provider value={user}&gt;
    &lt;CartContext.Provider value={cart}&gt;
      {children}
    &lt;/CartContext.Provider&gt;
  &lt;/AuthContext.Provider&gt;
&lt;/ThemeContext.Provider&gt;
</code></pre>
<p>Each context now updates independently. A cart change doesn't wake up your theme consumers.</p>
<h3>Memoize Your Context Value</h3>
<p>When your context value is an object, React creates a <strong>new object reference on every render</strong> — which triggers all consumers even if the data hasn't changed. Fix it with <code>useMemo</code>:</p>
<pre><code class="language-jsx">// Without useMemo, this object is new every render
const value = useMemo(() =&gt; ({
  user,
  login,
  logout,
}), [user]); // Only recreates when 'user' actually changes
</code></pre>
<h3>Quick Performance Checklist</h3>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Recommendation</th>
</tr>
</thead>
<tbody><tr>
<td>Slow-changing data (theme, user)</td>
<td>✅ Great fit for context</td>
</tr>
<tr>
<td>High-frequency updates (scroll, mouse)</td>
<td>❌ Avoid context, use local state</td>
</tr>
<tr>
<td>Large shared object</td>
<td>⚠️ Split into multiple contexts</td>
</tr>
<tr>
<td>Object as context value</td>
<td>✅ Wrap in useMemo</td>
</tr>
</tbody></table>
<hr />
<h2>7. Use Cases — Where useContext Shines</h2>
<p>Here are the situations where useContext is the right tool for the job:</p>
<p><strong>Theme / Dark Mode</strong> — Store the active color scheme globally. Any component can read and respond to theme changes without a single prop.</p>
<p><strong>Authentication</strong> — Share the logged-in user's profile, permissions, and auth actions (login/logout) across every page and component.</p>
<p><strong>Internationalization (i18n)</strong> — Provide the active locale and translation function app-wide so every piece of text can render in the right language.</p>
<p><strong>Shopping Cart</strong> — Track cart items and totals globally so the Navbar badge, product pages, and checkout all stay in sync.</p>
<p><strong>Notifications / Toast Messages</strong> — Trigger alerts from deep inside a component tree without wiring up callbacks all the way to the root.</p>
<p><strong>App-wide Preferences</strong> — Font size, currency, accessibility settings — any user preference that multiple unrelated components need to respect.</p>
<hr />
<h2>8. useContext vs Redux / Zustand</h2>
<p>A very common question: <em>"Now that we have useContext, do we still need Redux?"</em></p>
<p>Honest answer — sometimes yes, sometimes no. They solve slightly different problems.</p>
<table>
<thead>
<tr>
<th></th>
<th>useContext</th>
<th>Redux / Zustand</th>
</tr>
</thead>
<tbody><tr>
<td>Setup complexity</td>
<td>Minimal, zero dependencies</td>
<td>Moderate to high</td>
</tr>
<tr>
<td>DevTools &amp; debugging</td>
<td>Basic</td>
<td>Excellent (time-travel, action logs)</td>
</tr>
<tr>
<td>Performance at scale</td>
<td>Needs careful context splitting</td>
<td>Built-in selectors prevent re-renders</td>
</tr>
<tr>
<td>Async / middleware</td>
<td>Not built-in</td>
<td>Yes (thunk, saga, etc.)</td>
</tr>
<tr>
<td>Bundle size</td>
<td>Zero (built into React)</td>
<td>Adds external dependencies</td>
</tr>
<tr>
<td>Best for</td>
<td>Slow-changing, app-wide config</td>
<td>Frequent updates, complex async logic</td>
</tr>
</tbody></table>
<p><strong>The rule of thumb:</strong> Use useContext for things that change infrequently and are needed broadly — theme, auth, locale. Reach for Redux or Zustand when your state updates often, your logic is complex, or you need powerful debugging tools.</p>
<p>Many mature apps use both — context for global config, a dedicated store for business logic.</p>
<hr />
<h2>9. Summary — The useContext Cheat Sheet</h2>
<p>Here's everything in one place:</p>
<ol>
<li><p><strong>Create</strong> — <code>const MyContext = createContext(defaultValue)</code></p>
</li>
<li><p><strong>Provide</strong> — Wrap your tree with <code>&lt;MyContext.Provider value={...}&gt;</code></p>
</li>
<li><p><strong>Consume</strong> — Read anywhere with <code>const val = useContext(MyContext)</code></p>
</li>
<li><p><strong>Abstract</strong> — Wrap in a custom hook (<code>useAuth</code>, <code>useTheme</code>) for a clean API</p>
</li>
<li><p><strong>Split</strong> — Separate contexts by concern to avoid cascading re-renders</p>
</li>
<li><p><strong>Memoize</strong> — Wrap object values in <code>useMemo</code> to stabilize references</p>
</li>
</ol>
<blockquote>
<p><strong>One thing to avoid:</strong> Don't reach for context for everything. Local UI state — dropdown open/closed, form input values, hover states — still belongs in <code>useState</code> inside the component. Context is for data that truly needs to be <em>global</em>.</p>
</blockquote>
<p>useContext is one of those hooks that quietly makes your entire codebase cleaner once you internalize the pattern. Start by picking one prop you've been drilling through three or more components and migrate it to context. The clarity you get back is immediate.</p>
]]></content:encoded></item><item><title><![CDATA[Heaps & Priority Queue in DSA]]></title><description><![CDATA[A Heap is a specialized tree-based data structure that satisfies the Heap Property and is mainly used to implement Priority Queues and efficient sorting algorithms like Heap Sort.
It is one of the mos]]></description><link>https://yashrajxdev.blog/heaps-priority-queue-in-dsa</link><guid isPermaLink="true">https://yashrajxdev.blog/heaps-priority-queue-in-dsa</guid><category><![CDATA[DSA]]></category><category><![CDATA[Python]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[python programming]]></category><category><![CDATA[leetcode]]></category><category><![CDATA[FAANG]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sun, 08 Mar 2026 04:31:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/40b3b08d-5d6a-4f91-8b65-0cd504fa84b2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A <strong>Heap</strong> is a specialized tree-based data structure that satisfies the <strong>Heap Property</strong> and is mainly used to implement <strong>Priority Queues</strong> and efficient sorting algorithms like <strong>Heap Sort</strong>.</p>
<p>It is one of the most frequently asked topics in DSA interviews.</p>
<hr />
<h2>What is a Heap?</h2>
<p>A heap is a <strong>Complete Binary Tree</strong>, which means:</p>
<ul>
<li><p>All levels are completely filled</p>
</li>
<li><p>The last level is filled from <mark class="bg-yellow-200 dark:bg-yellow-500/30">left to right</mark></p>
</li>
</ul>
<p>Heaps are typically implemented using <strong>arrays</strong>, not pointer-based trees.</p>
<hr />
<h2>Heap Property</h2>
<p>There are two types of heaps:</p>
<h3>🔹 Min-Heap</h3>
<ul>
<li><p>Parent node is <strong>smaller</strong> than its children</p>
</li>
<li><p><mark class="bg-yellow-200 dark:bg-yellow-500/30">The smallest element is always at the root</mark></p>
</li>
</ul>
<h3>🔹 Max-Heap</h3>
<ul>
<li><p>Parent node is <strong>greater</strong> than its children</p>
</li>
<li><p><mark class="bg-yellow-200 dark:bg-yellow-500/30">The largest element is always at the root</mark></p>
</li>
</ul>
<p>In Python, the <code>heapq</code> module implements a <strong>Min-Heap by default</strong>.</p>
<hr />
<h1>Array Representation of Heap</h1>
<p>For a node at index <code>i</code> (0-based indexing):</p>
<ul>
<li><p>Left child → <code>2*i + 1</code></p>
</li>
<li><p>Right child → <code>2*i + 2</code></p>
</li>
<li><p>Parent → <code>(i - 1) // 2</code></p>
</li>
</ul>
<p>This is why heaps are implemented efficiently using arrays.</p>
<hr />
<h1>Common Heap Operations &amp; Time Complexity</h1>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Time Complexity</th>
</tr>
</thead>
<tbody><tr>
<td>Get Min/Max</td>
<td>O(1)</td>
</tr>
<tr>
<td>Insert</td>
<td>O(log n)</td>
</tr>
<tr>
<td>Remove Top</td>
<td>O(log n)</td>
</tr>
<tr>
<td>Heapify (Build Heap)</td>
<td>O(n)</td>
</tr>
<tr>
<td>Heap Sort</td>
<td>O(n log n)</td>
</tr>
</tbody></table>
<hr />
<h1>Using Heap in Python (<code>heapq</code>)</h1>
<hr />
<h2>1️⃣ Build Min Heap (Heapify)</h2>
<p>Time: <strong>O(n)</strong><br />Space: <strong>O(1)</strong> (in-place)</p>
<pre><code class="language-python">import heapq

A = [-4, 3, 1, 0, 2, 5, 10, 8, 12, 9]
heapq.heapify(A) #O(n)

print(A)
</code></pre>
<p><code>heapify()</code> converts a list into a valid heap in linear time.</p>
<p>⚡ Interview Insight:<br />Building a heap using repeated insertion takes O(n log n), but <code>heapify()</code> does it in O(n).</p>
<hr />
<h2>2️⃣ Insert into Heap</h2>
<p>Time: <strong>O(log n)</strong></p>
<pre><code class="language-python">heapq.heappush(A, 4)
print(A)
</code></pre>
<hr />
<h2>3️⃣ Extract Minimum</h2>
<p>Time: <strong>O(log n)</strong></p>
<pre><code class="language-python">min_val = heapq.heappop(A)
print(A, min_val)
</code></pre>
<hr />
<h2>4️⃣ Peek Minimum (Without Removing)</h2>
<p>Time: <strong>O(1)</strong></p>
<pre><code class="language-python">A[0]
</code></pre>
<p>The smallest element is always at index <code>0</code>.</p>
<hr />
<h2>5️⃣ Heappush + Heappop Combined</h2>
<p>Time: <strong>O(log n)</strong></p>
<pre><code class="language-python">heapq.heappushpop(A, 99)
print(A)
</code></pre>
<p>More efficient than doing push then pop separately.</p>
<hr />
<h1>Heap Sort in Python</h1>
<p>Time: <strong>O(n log n)</strong><br />Space: <strong>O(n)</strong> (extra list used)</p>
<pre><code class="language-python">def heapsort(arr):
    heapq.heapify(arr)
    result = []

    while arr:
        result.append(heapq.heappop(arr))

    return result

print(heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]))
</code></pre>
<p>⚠️ Note:<br />In-place heap sort with O(1) space is possible but more complex to implement manually.</p>
<hr />
<h1>Max Heap in Python</h1>
<p>Python does not directly support max-heap.<br />We simulate it by inserting <mark class="bg-yellow-200 dark:bg-yellow-500/30">negative values</mark>.</p>
<pre><code class="language-python">B = [-4, 3, 1, 0, 2, 5, 10, 8, 12, 9]

# Convert to negative
B = [-x for x in B]

heapq.heapify(B)

largest = -heapq.heappop(B)
print(largest)

# Insert 7
heapq.heappush(B, -7)
</code></pre>
<p>⚡ Interview Tip:<br />This technique is very commonly used in competitive programming.</p>
<hr />
<h1>Build Heap from Scratch (Using Insert)</h1>
<p>Time: <strong>O(n log n)</strong></p>
<pre><code class="language-python">C = [-5, 4, 2, 1, 7, 0, 3]
heap = []

for x in C:
    heapq.heappush(heap, x)
    print(heap)
</code></pre>
<p>Repeated insertion is slower than heapify.</p>
<hr />
<h1>Using Tuples in Heap</h1>
<p>Heaps can store <a href="https://yashrajxdev.blog/arrays-and-tuple-in-python">tuples</a>.</p>
<p>Python compares tuples element by element.</p>
<p>Example: Frequency-based sorting.</p>
<pre><code class="language-python">from collections import Counter
import heapq

D = [5, 4, 3, 5, 4, 3, 5, 5, 4]
counter = Counter(D)

heap = []

for key, value in counter.items():
    heapq.heappush(heap, (value, key))

print(heap)
</code></pre>
<p>This is used in:</p>
<ul>
<li><p>Top K Frequent Elements</p>
</li>
<li><p>Frequency Sorting</p>
</li>
<li><p>Scheduling Problems</p>
</li>
</ul>
<hr />
<h3>Priority Queue vs Heap</h3>
<p>A <strong>Priority Queue</strong> is an abstract data structure.</p>
<p>A <strong>Heap</strong> is one way to implement it efficiently.</p>
<p>Priority Queue ensures:</p>
<ul>
<li>Highest (or lowest) priority element is removed first.</li>
</ul>
<hr />
<h1>Median of Data Stream (Two Heaps Technique)</h1>
<p>One of the most popular heap-based interview problems is:</p>
<blockquote>
<p><strong>Design a data structure that supports adding numbers and finding the median at any time.</strong></p>
</blockquote>
<hr />
<h2>Problem Statement</h2>
<p>You continuously receive numbers from a data stream.</p>
<p>You must support two operations:</p>
<ol>
<li><p><code>addNum(num)</code> → Add a number</p>
</li>
<li><p><code>findMedian()</code> → Return the median of all inserted numbers</p>
</li>
</ol>
<hr />
<p><em><strong>Why Sorting Every Time Is Not Good?</strong></em></p>
<p>If you sort the array every time:</p>
<ul>
<li><p>Insertion → O(1)</p>
</li>
<li><p>Sorting → O(n log n)</p>
</li>
<li><p>Finding median → O(1)</p>
</li>
</ul>
<p>This is inefficient for large streams.</p>
<p>We need something better.</p>
<hr />
<h2>Optimal Approach: Two Heaps</h2>
<p>We use:</p>
<ul>
<li><p>🔹 <strong>Max Heap</strong> → Stores the smaller half of numbers</p>
</li>
<li><p>🔹 <strong>Min Heap</strong> → Stores the larger half of numbers</p>
</li>
</ul>
<h3>Why Two Heaps?</h3>
<p>We divide numbers into two balanced halves:</p>
<pre><code class="language-plaintext">Max Heap (left side)  |  Min Heap (right side)
Smaller numbers       |  Larger numbers
</code></pre>
<p>This ensures:</p>
<ul>
<li><p>Median is either:</p>
<ul>
<li><p>Top of one heap</p>
</li>
<li><p>Or average of tops of both heaps</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3>Important Rules</h3>
<ol>
<li><p>Size difference between heaps should <mark class="bg-yellow-200 dark:bg-yellow-500/30">not exceed 1</mark></p>
</li>
<li><p>All elements in max heap ≤ elements in min heap</p>
</li>
</ol>
<hr />
<h2>Python Implementation</h2>
<p>Since Python only provides a <strong>Min Heap</strong>,</p>
<p>we simulate a <strong>Max Heap</strong> using negative values.</p>
<pre><code class="language-python">import heapq

class MedianFinder:

    def __init__(self):
        self.small = []  # Max heap (invert values)
        self.large = []  # Min heap

    def addNum(self, num):

        # Step 1: Push to max heap (invert value)
        heapq.heappush(self.small, -num)

        # Step 2: Ensure ordering property
        if self.small and self.large and (-self.small[0] &gt; self.large[0]):
            value = -heapq.heappop(self.small)
            heapq.heappush(self.large, value)

        # Step 3: Balance sizes
        if len(self.small) &gt; len(self.large) + 1:
            value = -heapq.heappop(self.small)
            heapq.heappush(self.large, value)

        if len(self.large) &gt; len(self.small):
            value = heapq.heappop(self.large)
            heapq.heappush(self.small, -value)

    def findMedian(self):

        if len(self.small) &gt; len(self.large):
            return -self.small[0]

        return (-self.small[0] + self.large[0]) / 2
</code></pre>
<hr />
<h3>Time Complexity</h3>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Time Complexity</th>
</tr>
</thead>
<tbody><tr>
<td>addNum()</td>
<td>O(log n)</td>
</tr>
<tr>
<td>findMedian()</td>
<td>O(1)</td>
</tr>
</tbody></table>
<p>This is optimal.</p>
<hr />
<h3>Example</h3>
<p>Input Stream:</p>
<pre><code class="language-plaintext">1 → median = 1
1, 2 → median = 1.5
1, 2, 3 → median = 2
1, 2, 3, 4 → median = 2.5
</code></pre>
<p>Heaps internally balance automatically.</p>
]]></content:encoded></item><item><title><![CDATA[Linked Lists in DSA]]></title><description><![CDATA[Unlike arrays, where insertion in the middle takes O(N) time due to shifting elements, a Linked List allows insertion without shifting.
In this blog, we will use LL as short form for Linked List.
What]]></description><link>https://yashrajxdev.blog/linked-lists-in-dsa</link><guid isPermaLink="true">https://yashrajxdev.blog/linked-lists-in-dsa</guid><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 28 Feb 2026 13:22:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/58285f9b-40ae-4579-85ba-34ab1d5c5226.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Unlike arrays, where insertion in the middle takes <strong>O(N)</strong> time due to shifting elements, a <strong>Linked List</strong> allows insertion without shifting.</p>
<p>In this blog, we will use <strong>LL</strong> as short form for Linked List.</p>
<h2>What is a Linked List?</h2>
<p>A <strong>Linked List</strong> is a collection of individual nodes connected using memory addresses (references).</p>
<p>Each node contains:</p>
<ul>
<li><p>A <strong>value</strong></p>
</li>
<li><p>A reference (pointer) to the <strong>next node</strong></p>
</li>
</ul>
<p>We do not store elements in continuous memory like arrays.</p>
<h2>Head of Linked List</h2>
<p>Every linked list has a starting point called the <strong>Head</strong>.</p>
<ul>
<li><p>The head points to the first node.</p>
</li>
<li><p>In most problems, the head is already given to you.</p>
</li>
<li><p>All operations (traversal, insertion, deletion) start from the head.</p>
</li>
</ul>
<h2>Structure of a Node (Singly Linked List)</h2>
<p>Here is the correct Python structure:</p>
<pre><code class="language-python">class Node:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
</code></pre>
<h3>Explanation:</h3>
<ul>
<li><p><code>val</code> → stores the data.</p>
</li>
<li><p><code>next</code> → stores the reference to the next node.</p>
</li>
<li><p><code>None</code> means there is no next node (end of the list).</p>
</li>
</ul>
<h2>Traversal of Linked List</h2>
<p>To traverse a linked list:</p>
<ul>
<li><p>Start from <code>head</code></p>
</li>
<li><p>Move until it becomes <code>None</code></p>
</li>
</ul>
<p>In Python, we use <code>None</code> instead of <code>null</code>.</p>
<pre><code class="language-python">def traverse(head):
    while head:
        print(head.val)
        head = head.next   # Move to next node
</code></pre>
<p>Time Complexity → <strong>O(N)</strong></p>
<hr />
<h2>Types of Linked Lists</h2>
<h3>1️⃣ Singly Linked List</h3>
<ul>
<li><p>Each node points to the next node only.</p>
</li>
<li><p>Traversal is possible in one direction only.</p>
</li>
</ul>
<h3>2️⃣ Doubly Linked List</h3>
<p>In a doubly linked list:</p>
<ul>
<li><p>Each node stores reference to:</p>
<ul>
<li><p>Next node</p>
</li>
<li><p>Previous node</p>
</li>
</ul>
</li>
<li><p>We usually maintain both <strong>Head</strong> and <strong>Tail</strong>.</p>
</li>
</ul>
<p>Structure:</p>
<pre><code class="language-python">class DoublyNode:
    def __init__(self, val, next=None, prev=None):
        self.val = val
        self.next = next
        self.prev = prev
</code></pre>
<p>Advantages:</p>
<ul>
<li><p>Can traverse in both directions.</p>
</li>
<li><p>Deletion becomes easier if node reference is given.</p>
</li>
</ul>
<hr />
<h1>Reverse a Linked List</h1>
<p>This is one of the most commonly asked DSA interview questions.</p>
<p>There are two ways to reverse a linked list:</p>
<h2>1️⃣ Iterative Approach</h2>
<pre><code class="language-python">def reverse_ll_iterative(head):
    prev = None
    current = head  # Always use a separate pointer for traversal

    while current:
        next_node = current.next
        current.next = prev
        prev = current
        current = next_node

    return prev
</code></pre>
<h3>Time Complexity → O(N)</h3>
<h3>Space Complexity → O(1)</h3>
<p>Why interviewers prefer this:</p>
<ul>
<li><p>Efficient</p>
</li>
<li><p>No extra space</p>
</li>
<li><p>Clear pointer manipulation understanding</p>
</li>
</ul>
<h2>2️⃣ Recursive Approach</h2>
<p>Corrected version:</p>
<pre><code class="language-python">def reverse_ll_recursive(head):
    if not head or not head.next:
        return head

    new_head = reverse_ll_recursive(head.next)

    head.next.next = head
    head.next = None

    return new_head
</code></pre>
<h3>Time Complexity → O(N)</h3>
<h3>Space Complexity → O(N) (because of recursion stack)</h3>
<p>⚠️ Important:<br />In interviews, mention that recursion uses extra stack space.</p>
<hr />
<p>Linked lists are used in:</p>
<ul>
<li><p>Stack and Queue implementation</p>
</li>
<li><p>LRU Cache</p>
</li>
<li><p>Hash collisions (chaining)</p>
</li>
<li><p>Graph adjacency list</p>
</li>
<li><p>Merge Two Sorted Lists</p>
</li>
<li><p>Detect Cycle (Floyd’s Algorithm)</p>
</li>
</ul>
<p>If you understand pointer manipulation clearly, many advanced problems become easier.</p>
]]></content:encoded></item><item><title><![CDATA[Graph in DSA ]]></title><description><![CDATA[What is a Graph?
A Graph is a data structure used to represent relationships between different entities.
It consists of:

Vertices (Nodes) → Represent entities

Edges → Represent connections between n]]></description><link>https://yashrajxdev.blog/graph-in-dsa</link><guid isPermaLink="true">https://yashrajxdev.blog/graph-in-dsa</guid><category><![CDATA[DSA]]></category><category><![CDATA[Python]]></category><category><![CDATA[graphs]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 28 Feb 2026 13:16:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6942d60438f3c2af46f04eed/ae0b64d3-fdb8-4d6d-ba1b-b4e0105b51a3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>What is a Graph?</h2>
<p>A <strong>Graph</strong> is a data structure used to represent relationships between different entities.</p>
<p>It consists of:</p>
<ul>
<li><p><strong>Vertices (Nodes)</strong> → Represent entities</p>
</li>
<li><p><strong>Edges</strong> → Represent connections between nodes</p>
</li>
</ul>
<p>Example:</p>
<ul>
<li><p>Social networks</p>
</li>
<li><p>Maps and routes</p>
</li>
<li><p>Web pages linking to each other</p>
</li>
<li><p>Dependency graphs</p>
</li>
</ul>
<hr />
<h3>Types of Graphs</h3>
<p>1️⃣ <strong>Directed Graph</strong> → Edges have direction<br />2️⃣ <strong>Undirected Graph</strong> → Edges have no direction<br />3️⃣ <strong>Weighted Graph</strong> → Edges have weights (cost/distance)<br />4️⃣ <strong>Unweighted Graph</strong> → No weights</p>
<hr />
<h2>Graph Representation in Python</h2>
<p>Most common representation in DSA interviews:</p>
<h3>Adjacency List (Most Preferred)</h3>
<pre><code class="language-python">graph = {
    1: [2, 3],
    2: [4],
    3: [],
    4: []
}
</code></pre>
<p>This means:</p>
<ul>
<li><p>1 is connected to 2 and 3</p>
</li>
<li><p>2 is connected to 4</p>
</li>
</ul>
<p>Time-efficient and memory-efficient.</p>
<hr />
<h1>BFS (Breadth First Search)</h1>
<p>BFS explores level by level.</p>
<p>It uses a <strong>Queue</strong>.</p>
<h3>When to Use BFS?</h3>
<ul>
<li><p><mark class="bg-yellow-200 dark:bg-yellow-500/30">Shortest path</mark> in unweighted graph</p>
</li>
<li><p>Level order traversal</p>
</li>
<li><p>Finding minimum steps</p>
</li>
</ul>
<hr />
<h2>BFS Code (Python)</h2>
<pre><code class="language-python">from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)

    while queue:
        node = queue.popleft()
        print(node)

        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
</code></pre>
<h3>Time Complexity → O(V + E)</h3>
<hr />
<h2>Example Question (BFS)</h2>
<p><strong>Question:</strong> Find the shortest path from node 1 to all other nodes in an unweighted graph.</p>
<p>👉 Use BFS because it guarantees shortest path in unweighted graphs.</p>
<hr />
<h1>DFS (Depth First Search)</h1>
<p>DFS explores as deep as possible before backtracking.</p>
<p>It uses:</p>
<ul>
<li><p>Recursion (stack)</p>
</li>
<li><p>Or an explicit stack</p>
</li>
</ul>
<hr />
<h2>DFS Code (Recursive)</h2>
<pre><code class="language-python">def dfs(graph, node, visited):
    if node in visited:
        return

    visited.add(node)
    print(node)

    for neighbor in graph[node]:
        dfs(graph, neighbor, visited)
</code></pre>
<p>Call it like:</p>
<pre><code class="language-python">visited = set()
dfs(graph, 1, visited)
</code></pre>
<h3>Time Complexity → O(V + E)</h3>
<hr />
<h2>When to Use DFS?</h2>
<ul>
<li><p>Detect cycles</p>
</li>
<li><p>Backtracking problems</p>
</li>
<li><p>Topological sort</p>
</li>
<li><p>Checking connectivity</p>
</li>
</ul>
<hr />
<h3>Example Question (DFS)</h3>
<p><strong>Question:</strong> Detect if a graph has a cycle.</p>
<p>👉 DFS is commonly used for cycle detection.</p>
<hr />
<h1>Dijkstra’s Algorithm</h1>
<p>Used to find the <strong>shortest path in a weighted graph</strong>.</p>
<p>⚠️ Works only when weights are non-negative.</p>
<hr />
<h2>When to Use Dijkstra?</h2>
<ul>
<li><p>Shortest path in weighted graph</p>
</li>
<li><p>Network routing</p>
</li>
<li><p>Map navigation systems</p>
</li>
</ul>
<hr />
<h2>Example Graph (Weighted)</h2>
<pre><code class="language-python">graph = {
    0: [(1, 4), (2, 1)],
    1: [(3, 1)],
    2: [(1, 2), (3, 5)],
    3: []
}
</code></pre>
<p>Each tuple: <code>(neighbor, weight)</code></p>
<hr />
<h2>Dijkstra’s Algorithm Code (Python)</h2>
<pre><code class="language-python">import heapq

def dijkstra(graph, start):
    min_heap = [(0, start)]  # (distance, node)
    distances = {node: float('inf') for node in graph}
    distances[start] = 0

    while min_heap:
        current_distance, current_node = heapq.heappop(min_heap)

        if current_distance &gt; distances[current_node]:
            continue

        for neighbor, weight in graph[current_node]:
            distance = current_distance + weight

            if distance &lt; distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(min_heap, (distance, neighbor))

    return distances
</code></pre>
<hr />
<h2>Time Complexity of Dijkstra</h2>
<p>Using Min-Heap (Priority Queue):</p>
<p>👉 <strong>O((V + E) log V)</strong></p>
<hr />
<h3>Example Question (Dijkstra)</h3>
<p><strong>Question:</strong> Given a weighted graph and a source node, find the shortest path to all other nodes.</p>
<p>👉 Use Dijkstra if:</p>
<ul>
<li><p>Weights are non-negative</p>
</li>
<li><p>You need shortest path</p>
</li>
</ul>
<hr />
<p>Graphs are one of the most powerful and frequently asked topics in DSA interviews.<br />If you master BFS, DFS, and Dijkstra, you can solve a large percentage of graph problems confidently.</p>
]]></content:encoded></item><item><title><![CDATA[Arrays and Tuple in Python]]></title><description><![CDATA[An array is a continuous block of memory used to store similar or structured data.
Arrays allow easy and fast access to elements using an index, which makes them one of the most important data structu]]></description><link>https://yashrajxdev.blog/arrays-and-tuple-in-python</link><guid isPermaLink="true">https://yashrajxdev.blog/arrays-and-tuple-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[data structure and algorithms ]]></category><category><![CDATA[leetcode]]></category><category><![CDATA[DSA in Python]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sun, 22 Feb 2026 01:53:32 GMT</pubDate><enclosure url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/6942d60438f3c2af46f04eed/bde94105-5d4e-40a3-b63a-2d4468c100e0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>An <strong>array</strong> is a continuous block of memory used to store similar or structured data.</p>
<p>Arrays allow <strong>easy and fast access</strong> to elements using an index, which makes them one of the most important data structures in DSA.</p>
<p>In Python, we don’t have traditional arrays like in C++ or Java.<br />Instead, we use something called a <strong><mark>List</mark></strong>.</p>
<h2>Python Lists (Dynamic Arrays)</h2>
<p>In Python, a list is a <strong>dynamic array</strong>.</p>
<h3>Example:</h3>
<pre><code class="language-python">arr = [1, 2, 3, 4, 5]
</code></pre>
<h3><strong>Key Characteristics:</strong></h3>
<ul>
<li><p>Lists are <strong>mutable</strong> → They can be changed after declaration.</p>
</li>
<li><p>They are <strong>dynamic</strong> → Their size can grow or shrink.</p>
</li>
<li><p>They allow <strong>index-based access</strong> → <code>arr[0]</code>, <code>arr[1]</code>, etc.</p>
</li>
</ul>
<hr />
<h2>Static vs Dynamic Arrays</h2>
<h3>🔹 Static Array</h3>
<ul>
<li><p>Size is fixed.</p>
</li>
<li><p>Cannot grow after creation.</p>
</li>
<li><p>Example: Arrays in C++</p>
</li>
</ul>
<h3>🔹 Dynamic Array (Python List)</h3>
<ul>
<li><p>Size can increase or decrease.</p>
</li>
<li><p>Memory is managed automatically.</p>
</li>
<li><p>Used in almost all DSA problems in Python.</p>
</li>
</ul>
<hr />
<h2>Important List Operations</h2>
<h3>1️⃣ Access by Index → <strong>O(1)</strong></h3>
<pre><code class="language-python">arr[2]
</code></pre>
<p>Accessing an element using an index is constant time.</p>
<hr />
<h3>2️⃣ Searching for an Element → <strong>O(N)</strong></h3>
<pre><code class="language-python">if 5 in arr:
    print(True)
</code></pre>
<p>This takes <strong>O(N)</strong> time because Python needs to traverse the list element by element.</p>
<hr />
<h3>3️⃣ Important Dynamic Array Methods</h3>
<h4>✅ <code>append()</code> → O(1) (Amortized)</h4>
<pre><code class="language-python">arr.append(6)
</code></pre>
<ul>
<li><p>Adds an element to the end.</p>
</li>
<li><p>Amortized O(1) means most of the time it is constant time.</p>
</li>
<li><p>Occasionally, resizing happens internally, which takes O(N), but overall average remains O(1).</p>
</li>
</ul>
<hr />
<h4>✅ <code>pop()</code> → O(1)</h4>
<pre><code class="language-python">arr.pop()
</code></pre>
<ul>
<li><p>Removes the last element.</p>
</li>
<li><p>Constant time operation.</p>
</li>
</ul>
<p>⚠️ <code>pop(index)</code> is O(N) because shifting is required.</p>
<hr />
<h4>✅ <code>insert(index, value)</code> → O(N)</h4>
<pre><code class="language-python">arr.insert(2, 10)
</code></pre>
<ul>
<li><p>Inserts element at a specific position.</p>
</li>
<li><p>All elements after that index need to shift.</p>
</li>
<li><p>Therefore, time complexity is O(N).</p>
</li>
</ul>
<hr />
<h4>✅ <code>len()</code> → O(1)</h4>
<pre><code class="language-python">len(arr)
</code></pre>
<ul>
<li><p>Returns the number of elements in the list.</p>
</li>
<li><p>Constant time operation.</p>
</li>
</ul>
<hr />
<h2>Why Arrays (Lists) Are Extremely Important in DSA</h2>
<p>Most beginner DSA problems are based on arrays:</p>
<ul>
<li><p>Two Sum</p>
</li>
<li><p>Sliding Window</p>
</li>
<li><p>Prefix Sum</p>
</li>
<li><p><a href="https://neetcode.io/courses/advanced-algorithms/0">Kadane’s Algorithm</a></p>
</li>
<li><p>Sorting</p>
</li>
<li><p>Binary Search</p>
</li>
</ul>
<hr />
<h1>Tuples</h1>
<p>A <strong>tuple</strong> in Python is an ordered collection of elements, just like a list.</p>
<p>However, the key difference is:</p>
<p>👉 <strong><mark>Tuples are immutable.</mark></strong></p>
<p>Once a tuple is created, its values cannot be changed.</p>
<h2>How to Create a Tuple</h2>
<pre><code class="language-python">t = (1, 2, 3, 4)
</code></pre>
<p>You can also create a tuple without parentheses:</p>
<pre><code class="language-python">t = 1, 2, 3
</code></pre>
<hr />
<h2>Tuple vs List (Important Difference)</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>List</th>
<th>Tuple</th>
</tr>
</thead>
<tbody><tr>
<td>Mutable</td>
<td>✅ Yes</td>
<td>❌ No</td>
</tr>
<tr>
<td>Syntax</td>
<td><code>[ ]</code></td>
<td><code>( )</code></td>
</tr>
<tr>
<td>Performance</td>
<td>Slightly slower</td>
<td>Slightly faster</td>
</tr>
<tr>
<td>Use Case</td>
<td>When data may change</td>
<td>When data should not change</td>
</tr>
</tbody></table>
<hr />
<h2>Why Tuples Matter in DSA</h2>
<p>Although tuples are not used as frequently as lists in basic DSA problems, they are very useful in certain scenarios:</p>
<h3>1️⃣ Returning Multiple Values from a Function</h3>
<pre><code class="language-python">def min_max(arr):
    return (min(arr), max(arr))
</code></pre>
<h3>2️⃣ Storing Fixed Data</h3>
<p>For example:</p>
<ul>
<li><p>Coordinates → <code>(x, y)</code></p>
</li>
<li><p>Graph edges → <code>(node1, node2)</code></p>
</li>
<li><p>Key-value pairs</p>
</li>
</ul>
<hr />
<h2>Important Interview Insight ⚡</h2>
<h3>🔹 Tuples are Hashable (if elements are immutable)</h3>
<p>This means they can be used as keys in dictionaries or stored inside sets.</p>
<p>Example:</p>
<pre><code class="language-python">visited = set()
visited.add((1, 2))
</code></pre>
<p>This is very common in:</p>
<ul>
<li><p>Graph problems</p>
</li>
<li><p>Grid-based problems</p>
</li>
<li><p>Backtracking problems</p>
</li>
</ul>
<p>Lists cannot be used as dictionary keys because they are mutable.</p>
<hr />
<h2>Time Complexity</h2>
<ul>
<li><p>Index access → <strong>O(1)</strong></p>
</li>
<li><p>Searching → <strong>O(N)</strong></p>
</li>
<li><p>No append, insert, or remove (because immutable)</p>
</li>
</ul>
<hr />
<h2>When Should You Use a Tuple?</h2>
<p>Use a tuple when:</p>
<ul>
<li><p>Data should not change</p>
</li>
<li><p>You want slightly better performance</p>
</li>
<li><p>You need to use the value as a dictionary key</p>
</li>
<li><p>You are returning multiple values from a function</p>
</li>
</ul>
<hr />
<h2>Key Takeaway</h2>
<p>Tuples are like "fixed lists."<br />They protect your data from accidental modification and are especially useful in hashing-related problems in DSA.</p>
]]></content:encoded></item><item><title><![CDATA[Strings in Python]]></title><description><![CDATA[In Python, strings are immutable.
This means once a string is created, it cannot be changed.
Example:
s = "python"

s[0] = "P"   # ❌ This will give an error

You cannot modify a character directly ins]]></description><link>https://yashrajxdev.blog/strings-in-python</link><guid isPermaLink="true">https://yashrajxdev.blog/strings-in-python</guid><category><![CDATA[DSA]]></category><category><![CDATA[Python]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[Strings]]></category><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[leetcode]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 21 Feb 2026 11:49:48 GMT</pubDate><enclosure url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/6942d60438f3c2af46f04eed/fcec642e-7f98-4da4-b6b3-cf98e8d47641.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Python, <strong>strings are immutable</strong>.</p>
<p>This means once a string is created, it <strong>cannot be changed</strong>.</p>
<h3>Example:</h3>
<pre><code class="language-python">s = "python"

s[0] = "P"   # ❌ This will give an error
</code></pre>
<p>You cannot modify a character directly inside a string.</p>
<hr />
<h2>What Does “Immutable” Mean?</h2>
<p>If you try to change a string, Python does not modify the original string.<br />Instead, it creates a <strong>new string</strong> in memory.</p>
<p>Example:</p>
<pre><code class="language-python">s = "python"
s = "Python"
</code></pre>
<p>Here, a new string is created.</p>
<hr />
<h3>Some of the most common and useful string methods are:</h3>
<p><strong>Case Conversion:</strong> upper(), lower(), capitalize(), title(), and swapcase() allow for changing the casing of strings.</p>
<p><strong>Searching:</strong> Methods like find(), index(), and count() locate or count substrings, while startswith() and endswith() check string boundaries.</p>
<p><strong>Modification:</strong> strip() (and lstrip()/rstrip()) removes whitespace, replace() substitutes substrings, split() divides strings into lists, and join() concatenates iterables.</p>
<p><strong>Formatting/Validation:</strong> format() or f-strings are used for string formatting, while isalpha(), isdigit(), and isalnum() validate string content.</p>
<hr />
<h2>Why Is This Important in DSA?</h2>
<p>Many interview problems are based on strings:</p>
<ul>
<li><p>Palindrome problems</p>
</li>
<li><p>Anagram checking</p>
</li>
<li><p>Substring problems</p>
</li>
<li><p>Pattern matching</p>
</li>
<li><p>Sliding window on strings</p>
</li>
</ul>
<p>Because strings are immutable:</p>
<ul>
<li><p>You cannot modify characters directly.</p>
</li>
<li><p>You often convert strings into lists when modification is required.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-python">s = "python"
s_list = list(s)
s_list[0] = "P"
s = "".join(s_list)
</code></pre>
<hr />
<h2>Searching in a String → O(N)</h2>
<p>You can check whether a character exists in a string using:</p>
<pre><code class="language-python">if "a" in s:
    print(True)
</code></pre>
<p>This operation takes <strong>O(N)</strong> time because Python may need to traverse the entire string.</p>
<hr />
<p>Time Complexity :</p>
<ul>
<li><p>Index access → <strong>O(1)</strong></p>
</li>
<li><p>Searching → <strong>O(N)</strong></p>
</li>
<li><p>Concatenation inside a loop → Can become <strong>O(N²)</strong> (be careful!)</p>
</li>
</ul>
<p>For large string manipulation problems, consider:</p>
<ul>
<li><p>Using a list for modification</p>
</li>
<li><p>Using <code>join()</code> instead of repeated concatenation</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Python for DSA]]></title><description><![CDATA[Introduction
DSA (Data Structures and Algorithms) is one of the most important subjects to learn as a coder or software engineer. Most companies test DSA concepts during technical interviews.
In real-world jobs, you may not directly implement complex...]]></description><link>https://yashrajxdev.blog/python-for-dsa</link><guid isPermaLink="true">https://yashrajxdev.blog/python-for-dsa</guid><category><![CDATA[Python]]></category><category><![CDATA[DSA]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[tutorials]]></category><category><![CDATA[data structure and algorithms ]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Wed, 18 Feb 2026 17:47:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1771053217773/daedea81-bea8-4e67-8cb0-c5c526c5d1c7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>DSA (Data Structures and Algorithms) is one of the most important subjects to learn as a coder or software engineer. Most companies test DSA concepts during technical interviews.</p>
<p>In real-world jobs, you may not directly implement complex DSA algorithms every day (except for applying the core concepts and logic). Still, companies strongly focus on DSA during interviews.</p>
<p>The reason behind this is not just to check whether you know trees or graphs. The real purpose is to evaluate your problem-solving skills — how you approach complex and large problems, how you break them down, and how you handle a task without going blank.</p>
<p>This is what truly matters.</p>
<p>Nowadays, simply memorizing syntax is not enough. Many companies even allow candidates to use Google or AI tools to look up syntax or small code snippets. However, tools cannot replace logical thinking.</p>
<p>To solve problems efficiently, you still need to remember basic syntax — such as how to use queues, define variables, write loops, and apply built-in functions. Knowing these fundamentals reduces the time spent searching for syntax and allows you to focus completely on the logic of solving the problem.</p>
<p><strong><em><mark>And in DSA, logic is everything.</mark></em></strong></p>
<h1 id="heading-why-choose-python">Why choose python ?</h1>
<p>You can choose any programming language to learn DSA.</p>
<p>However, most people usually pick one of these three:</p>
<ul>
<li><p>C++</p>
</li>
<li><p>Java</p>
</li>
<li><p>Python</p>
</li>
</ul>
<p>Among these, Python has the simplest and most readable syntax. It is easy to understand and easier to remember compared to the others.</p>
<p>If you are a working professional, you are likely already using a different language or framework in your job. Learning DSA in a language with heavy syntax can sometimes feel overwhelming.</p>
<p>That is why Python is a great choice. You spend less time worrying about syntax and more time focusing on logic and problem-solving. It helps you conserve mental energy and use your brainpower where it truly matters — <mark>solving problems</mark>.</p>
<p>In this blog, we will focus only on the essential concepts and syntax required for DSA. No unnecessary theory, no extra distractions — just what you actually need to remember.</p>
<p>Let’s get started. 🚀</p>
<hr />
<h3 id="heading-variables-in-python">Variables in Python :</h3>
<p>In Python, defining a variable is very simple.<br />You only need to write the variable name and assign a value to it. There is <strong><mark>no need to explicitly mention the data type</mark></strong> like in C++ or Java.</p>
<p>This is one of the biggest reasons why Python is beginner-friendly and widely used for learning <strong>Data Structures and Algorithms (DSA)</strong>.</p>
<p><strong>Example :</strong></p>
<pre><code class="lang-python">string = <span class="hljs-string">"python for dsa"</span>
number = <span class="hljs-number">2</span>
floating_number = <span class="hljs-number">2.9869</span>
character = <span class="hljs-string">"c"</span>
bit = <span class="hljs-number">0</span> 
largest_number = float(<span class="hljs-string">"inf"</span>) 
smallest_number = float(<span class="hljs-string">"-inf"</span>)
</code></pre>
<p><strong>Why This Matters in DSA</strong></p>
<p>In languages like C++ or Java, you must define the data type explicitly:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">int</span> number = <span class="hljs-number">2</span>;
</code></pre>
<p>But in Python, the interpreter automatically detects the type. This feature is called <strong><mark>dynamic typing</mark></strong><mark>.</mark></p>
<p><strong>Important for Interviews ⚡</strong></p>
<p>When solving DSA problems:</p>
<ul>
<li><p>You often need variables to store counts, indexes, flags, or temporary values.</p>
</li>
<li><p>You may need very large or very small values while comparing numbers.</p>
</li>
<li><p><code>float("inf")</code> and <code>float("-inf")</code> are extremely useful in problems like:</p>
<ul>
<li><p>Finding minimum or maximum values</p>
</li>
<li><p>Binary search variations</p>
</li>
<li><p>Dynamic programming</p>
</li>
<li><p>Greedy algorithms</p>
</li>
</ul>
</li>
</ul>
<p>Example use case:</p>
<pre><code class="lang-cpp">min_value = <span class="hljs-keyword">float</span>(<span class="hljs-string">"inf"</span>)
</code></pre>
<p>This ensures that any number compared with <code>min_value</code> will be smaller initially.</p>
]]></content:encoded></item><item><title><![CDATA[How to Use useRef for Managing Mutable Values Without Re-renders]]></title><description><![CDATA[If you've spent any time working with React hooks, you've probably encountered situations where you need to store a value that persists across renders but doesn't need to trigger a re-render when it changes. That's exactly where useRef shines, and un...]]></description><link>https://yashrajxdev.blog/how-to-use-useref-for-managing-mutable-values-without-re-renders</link><guid isPermaLink="true">https://yashrajxdev.blog/how-to-use-useref-for-managing-mutable-values-without-re-renders</guid><category><![CDATA[React]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[webdev]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[javascript framework]]></category><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Tue, 27 Jan 2026 12:13:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769515446392/1a1c715f-772d-4ccc-9aa1-382574f107b9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've spent any time working with React hooks, you've probably encountered situations where you need to store a value that persists across renders but doesn't need to trigger a re-render when it changes. That's exactly where <a target="_blank" href="https://react.dev/reference/react/useRef"><code>useRef</code></a> shines, and understanding when and how to use it can make your React applications significantly more efficient.</p>
<h2 id="heading-what-makes-useref-different">What Makes useRef Different?</h2>
<p>At first glance, <code>useRef</code> might seem similar to <code>useState</code>. Both persist values across renders, both are React hooks, and both are tools for managing component state. But here's the crucial difference: when you update a ref, your component doesn't re-render. When you update state with <code>useState</code>, it does.</p>
<p>Think of <code>useRef</code> as a box that holds a value. You can put something in the box, take it out, or replace it with something else—all without React caring about what you're doing. The component won't re-render, no matter how many times you change what's inside.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> countRef = useRef(<span class="hljs-number">0</span>);

<span class="hljs-comment">// This will NOT cause a re-render</span>
countRef.current = countRef.current + <span class="hljs-number">1</span>;
</code></pre>
<p>Compare this to <code>useState</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

<span class="hljs-comment">// This WILL cause a re-render</span>
setCount(count + <span class="hljs-number">1</span>);
</code></pre>
<h2 id="heading-when-should-you-actually-use-useref">When Should You Actually Use useRef?</h2>
<p>The question isn't just "can I use <code>useRef</code>?" but "should I use <code>useRef</code>?" Here are the scenarios where it makes the most sense.</p>
<h3 id="heading-accessing-dom-elements-directly">Accessing DOM Elements Directly</h3>
<p>This is probably the most common use case, and it's the one that feels most natural coming from vanilla JavaScript. Sometimes you just need direct access to a DOM node—maybe to focus an input, measure an element's dimensions, or integrate with a third-party library that expects a DOM reference.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TextInputWithFocus</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> inputRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> handleFocus = <span class="hljs-function">() =&gt;</span> {
    inputRef.current.focus();
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{inputRef}</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleFocus}</span>&gt;</span>Focus the input<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>This pattern is clean, straightforward, and doesn't introduce any unnecessary re-renders.</p>
<h3 id="heading-storing-previous-values">Storing Previous Values</h3>
<p>One particularly useful pattern is storing the previous value of a prop or state. This lets you compare current and previous values without the complexity of additional state management.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">usePrevious</span>(<span class="hljs-params">value</span>) </span>{
  <span class="hljs-keyword">const</span> ref = useRef();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    ref.current = value;
  });

  <span class="hljs-keyword">return</span> ref.current;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params">{ count }</span>) </span>{
  <span class="hljs-keyword">const</span> previousCount = usePrevious(count);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Current: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Previous: {previousCount}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Changed by: {count - (previousCount || 0)}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>This works because <code>useEffect</code> runs after the render, so <code>ref.current</code> still holds the old value during the render phase.</p>
<h3 id="heading-managing-timers-and-intervals">Managing Timers and Intervals</h3>
<p>If you've ever tried to clear a timer in a React component, you know the pain of losing the timer ID between renders. <code>useRef</code> solves this elegantly.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Timer</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [seconds, setSeconds] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> intervalRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> startTimer = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (intervalRef.current !== <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span>;

    intervalRef.current = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      setSeconds(<span class="hljs-function"><span class="hljs-params">s</span> =&gt;</span> s + <span class="hljs-number">1</span>);
    }, <span class="hljs-number">1000</span>);
  };

  <span class="hljs-keyword">const</span> stopTimer = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (intervalRef.current === <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span>;

    <span class="hljs-built_in">clearInterval</span>(intervalRef.current);
    intervalRef.current = <span class="hljs-literal">null</span>;
  };

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (intervalRef.current !== <span class="hljs-literal">null</span>) {
        <span class="hljs-built_in">clearInterval</span>(intervalRef.current);
      }
    };
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Seconds: {seconds}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{startTimer}</span>&gt;</span>Start<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{stopTimer}</span>&gt;</span>Stop<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>The ref keeps track of the interval ID across renders, and we can reliably clear it when needed.</p>
<h3 id="heading-avoiding-stale-closures">Avoiding Stale Closures</h3>
<p>Here's where things get interesting. Sometimes you need the latest value of a prop or state inside a callback that doesn't re-create on every render. This is where refs can save you from the dreaded stale closure problem.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SearchComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [query, setQuery] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> latestQueryRef = useRef(query);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    latestQueryRef.current = query;
  }, [query]);

  <span class="hljs-keyword">const</span> handleSearch = useCallback(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// This always has the latest query value</span>
    <span class="hljs-comment">// even though handleSearch doesn't change</span>
    fetch(<span class="hljs-string">`/api/search?q=<span class="hljs-subst">${latestQueryRef.current}</span>`</span>)
      .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
      .then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(data));
  }, []); <span class="hljs-comment">// Empty deps - function never recreates</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
        <span class="hljs-attr">value</span>=<span class="hljs-string">{query}</span> 
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setQuery(e.target.value)} 
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleSearch}</span>&gt;</span>Search<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-common-pitfalls-and-how-to-avoid-them">Common Pitfalls and How to Avoid Them</h2>
<h3 id="heading-dont-read-refs-during-render">Don't Read Refs During Render</h3>
<p>This is the biggest mistake developers make with <code>useRef</code>. Reading <code>ref.current</code> during the render phase can lead to inconsistent behavior because refs don't trigger re-renders.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// ❌ Bad - reading ref during render</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BadExample</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> countRef = useRef(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> increment = <span class="hljs-function">() =&gt;</span> {
    countRef.current++;
  };

  <span class="hljs-comment">// This will always show 0 because changing the ref doesn't re-render</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{countRef.current}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}

<span class="hljs-comment">// ✅ Good - use state for values that affect the UI</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">GoodExample</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> increment = <span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
  };

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<h3 id="heading-remember-refs-are-synchronous">Remember: Refs are Synchronous</h3>
<p>Unlike state updates, which React batches and processes asynchronously, <mark> ref updates happen immediately and synchronously.</mark></p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Example</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> ref = useRef(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> {
    ref.current = <span class="hljs-number">1</span>;
    <span class="hljs-built_in">console</span>.log(ref.current); <span class="hljs-comment">// Logs 1 immediately</span>

    ref.current = <span class="hljs-number">2</span>;
    <span class="hljs-built_in">console</span>.log(ref.current); <span class="hljs-comment">// Logs 2 immediately</span>
  };
}
</code></pre>
<p>This can be both a blessing and a curse. It's great when you need immediate access to a value, but it means you need to be careful about when and how you update refs.</p>
<h2 id="heading-useref-vs-usestate-making-the-right-choice">useRef vs useState: Making the Right Choice</h2>
<p>The decision between <code>useRef</code> and <code>useState</code> comes down to one key question: does this value need to trigger a re-render when it changes?</p>
<p>Use <code>useState</code> when:</p>
<ul>
<li><p>The value affects what's rendered on screen</p>
</li>
<li><p>You need React to respond to changes in the value</p>
</li>
<li><p>The value is part of your component's visual state</p>
</li>
</ul>
<p>Use <code>useRef</code> when:</p>
<ul>
<li><p>The value doesn't affect the rendered output</p>
</li>
<li><p>You need to store metadata about your component</p>
</li>
<li><p>You're interacting with DOM elements directly</p>
</li>
<li><p>You need to avoid triggering re-renders for performance</p>
</li>
</ul>
<h2 id="heading-advanced-pattern-combining-useref-with-useeffect">Advanced Pattern: Combining useRef with useEffect</h2>
<p>One powerful pattern is using refs to track whether a component has mounted or to prevent certain effects from running on the initial render.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ComponentWithMountCheck</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> hasMounted = useRef(<span class="hljs-literal">false</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!hasMounted.current) {
      hasMounted.current = <span class="hljs-literal">true</span>;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// This only runs on updates, not on mount</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Data changed:'</span>, data);
    saveDataToLocalStorage(data);
  }, [data]);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{/* Your component */}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>This pattern is particularly useful when you want different behavior on mount versus subsequent updates.</p>
<h2 id="heading-performance-considerations">Performance Considerations</h2>
<p>Using <code>useRef</code> appropriately can significantly improve your component's performance. Since refs don't cause re-renders, they're perfect for storing values that change frequently but don't need to update the UI.</p>
<p>Consider a scroll position tracker:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ScrollTracker</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> scrollPositionRef = useRef(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [visibleSection, setVisibleSection] = useState(<span class="hljs-string">'top'</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> handleScroll = <span class="hljs-function">() =&gt;</span> {
      scrollPositionRef.current = <span class="hljs-built_in">window</span>.scrollY;

      <span class="hljs-comment">// Only update state (and trigger re-render) when crossing thresholds</span>
      <span class="hljs-keyword">if</span> (scrollPositionRef.current &gt; <span class="hljs-number">500</span> &amp;&amp; visibleSection !== <span class="hljs-string">'bottom'</span>) {
        setVisibleSection(<span class="hljs-string">'bottom'</span>);
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (scrollPositionRef.current &lt;= <span class="hljs-number">500</span> &amp;&amp; visibleSection !== <span class="hljs-string">'top'</span>) {
        setVisibleSection(<span class="hljs-string">'top'</span>);
      }
    };

    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'scroll'</span>, handleScroll);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'scroll'</span>, handleScroll);
  }, [visibleSection]);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Current section: {visibleSection}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>Here, we're tracking every scroll event with a ref (no re-renders), but only updating state when it actually matters for the UI.</p>
<h2 id="heading-real-world-example-debounced-search">Real-World Example: Debounced Search</h2>
<p>Let's put it all together with a practical example that combines several concepts:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DebouncedSearch</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [searchTerm, setSearchTerm] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> [results, setResults] = useState([]);
  <span class="hljs-keyword">const</span> timeoutRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> requestRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> performSearch = <span class="hljs-keyword">async</span> (term) =&gt; {
    <span class="hljs-keyword">if</span> (requestRef.current) {
      requestRef.current.abort();
    }

    <span class="hljs-keyword">const</span> controller = <span class="hljs-keyword">new</span> AbortController();
    requestRef.current = controller;

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/api/search?q=<span class="hljs-subst">${term}</span>`</span>, {
        <span class="hljs-attr">signal</span>: controller.signal
      });
      <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
      setResults(data);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-keyword">if</span> (error.name !== <span class="hljs-string">'AbortError'</span>) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Search failed:'</span>, error);
      }
    }
  };

  <span class="hljs-keyword">const</span> handleSearchChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> value = e.target.value;
    setSearchTerm(value);

    <span class="hljs-keyword">if</span> (timeoutRef.current) {
      <span class="hljs-built_in">clearTimeout</span>(timeoutRef.current);
    }

    timeoutRef.current = <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (value.trim()) {
        performSearch(value);
      } <span class="hljs-keyword">else</span> {
        setResults([]);
      }
    }, <span class="hljs-number">300</span>);
  };

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (timeoutRef.current) {
        <span class="hljs-built_in">clearTimeout</span>(timeoutRef.current);
      }
      <span class="hljs-keyword">if</span> (requestRef.current) {
        requestRef.current.abort();
      }
    };
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{searchTerm}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleSearchChange}</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search..."</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {results.map(result =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{result.id}</span>&gt;</span>{result.title}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>This example demonstrates several key <code>useRef</code> patterns: managing timers, handling cleanup, and tracking mutable values that don't need to cause re-renders.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>The <code>useRef</code> hook is one of those tools that seems simple on the surface but reveals its true power once you understand when and how to use it properly. It's not about replacing <code>useState</code>—it's about complementing it. Use refs for implementation details that don't affect the rendered output, and you'll write more efficient, cleaner React code.</p>
<p>The key takeaway? If changing a value should update what the user sees, use <code>useState</code>. If it's just something you need to remember between renders without affecting the UI, reach for <code>useRef</code>. Master this distinction, and you'll avoid a lot of common React performance issues while writing more maintainable code.</p>
]]></content:encoded></item><item><title><![CDATA[useRef Explained: Handling DOM Elements in React]]></title><description><![CDATA[Introduction
In React's declarative world, we typically let React handle DOM updates. However, there are times when you need to directly interact with DOM elements—focusing an input field, measuring an element's dimensions, or integrating with third-...]]></description><link>https://yashrajxdev.blog/useref-explained-handling-dom-elements-in-react</link><guid isPermaLink="true">https://yashrajxdev.blog/useref-explained-handling-dom-elements-in-react</guid><category><![CDATA[React]]></category><category><![CDATA[React Native]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[No Code]]></category><category><![CDATA[AI]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[CSS]]></category><category><![CDATA[software development]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 24 Jan 2026 16:21:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769269327391/aa43c14f-9ec5-4be6-b5c9-70ab4491fd80.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In React's declarative world, we typically let React handle DOM updates. However, there are times when you need to directly interact with DOM elements—focusing an input field, measuring an element's dimensions, or integrating with third-party libraries. This is where <code>useRef</code> becomes essential.</p>
<p>In this guide, we'll explore how to use <code>useRef</code> to access DOM nodes, starting from the basics and building up to production-ready patterns.</p>
<h2 id="heading-what-is-useref">What is useRef?</h2>
<p><code>useRef</code> is a React Hook that creates a <strong><em>mutable reference object</em></strong> that persists across re-renders. Unlike state, updating a ref doesn't trigger a component re-render, making it perfect for storing values that shouldn't affect the visual output.</p>
<h3 id="heading-basic-syntax">Basic Syntax</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myRef = useRef(initialValue);
</code></pre>
<p>The ref object has a single property called <code>current</code> that holds the actual value. When you attach a ref to a DOM element, React automatically sets <code>ref.current</code> to that DOM node.</p>
<h2 id="heading-your-first-ref-focusing-an-input">Your First Ref: Focusing an Input</h2>
<p>Let's start with the most common use case—focusing an input field when a component mounts.</p>
<h3 id="heading-basic-example">Basic Example</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useRef, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SearchBox</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> inputRef = useRef(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Focus the input when component mounts</span>
    inputRef.current.focus();
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
      <span class="hljs-attr">ref</span>=<span class="hljs-string">{inputRef}</span>
      <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> 
      <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Start typing..."</span> 
    /&gt;</span></span>
  );
}
</code></pre>
<p><strong>How it works:</strong></p>
<ol>
<li><p>We create a ref with <code>useRef(null)</code> (null is the initial value)</p>
</li>
<li><p>We attach the ref to the input using the <code>ref</code> attribute</p>
</li>
<li><p>React sets <code>inputRef.current</code> to the actual DOM element</p>
</li>
<li><p>In <code>useEffect</code>, we call <code>inputRef.current.focus()</code> to focus the input</p>
</li>
</ol>
<h2 id="heading-production-grade-example-advanced-search-component">Production-Grade Example: Advanced Search Component</h2>
<p>Here's a real-world example that demonstrates multiple ref patterns you'll use in production applications.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useRef, useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AdvancedSearchBar</span>(<span class="hljs-params">{ onSearch, autoFocus = false }</span>) </span>{
  <span class="hljs-keyword">const</span> [query, setQuery] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> [isSearching, setIsSearching] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> inputRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> searchTimeoutRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-comment">// Auto-focus on mount if specified</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (autoFocus &amp;&amp; inputRef.current) {
      inputRef.current.focus();
    }
  }, [autoFocus]);

  <span class="hljs-comment">// Cleanup timeout on unmount</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (searchTimeoutRef.current) {
        <span class="hljs-built_in">clearTimeout</span>(searchTimeoutRef.current);
      }
    };
  }, []);

  <span class="hljs-keyword">const</span> handleInputChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> value = e.target.value;
    setQuery(value);

    <span class="hljs-comment">// Clear existing timeout</span>
    <span class="hljs-keyword">if</span> (searchTimeoutRef.current) {
      <span class="hljs-built_in">clearTimeout</span>(searchTimeoutRef.current);
    }

    <span class="hljs-comment">// Debounce search</span>
    setIsSearching(<span class="hljs-literal">true</span>);
    searchTimeoutRef.current = <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      onSearch(value);
      setIsSearching(<span class="hljs-literal">false</span>);
    }, <span class="hljs-number">500</span>);
  };

  <span class="hljs-keyword">const</span> handleClear = <span class="hljs-function">() =&gt;</span> {
    setQuery(<span class="hljs-string">''</span>);
    onSearch(<span class="hljs-string">''</span>);
    <span class="hljs-comment">// Focus input after clearing</span>
    inputRef.current?.focus();
  };

  <span class="hljs-keyword">const</span> handleKeyDown = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (e.key === <span class="hljs-string">'Escape'</span>) {
      handleClear();
    }
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"search-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">ref</span>=<span class="hljs-string">{inputRef}</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{query}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span>
        <span class="hljs-attr">onKeyDown</span>=<span class="hljs-string">{handleKeyDown}</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search..."</span>
        <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Search input"</span>
        <span class="hljs-attr">aria-busy</span>=<span class="hljs-string">{isSearching}</span>
      /&gt;</span>
      {query &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> 
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClear}</span>
          <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Clear search"</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
        &gt;</span>
          Clear
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      )}
      {isSearching &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Searching...<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-key-patterns-demonstrated">Key Patterns Demonstrated</h3>
<p><strong>1. Conditional Focus</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (autoFocus &amp;&amp; inputRef.current) {
  inputRef.current.focus();
}
</code></pre>
<p>Always check if <code>ref.current</code> exists before accessing it. This prevents errors during initial render or if the component unmounts.</p>
<p><strong>2. Multiple Refs</strong> We use two refs: one for the DOM node (<code>inputRef</code>) and one for storing the timeout ID (<code>searchTimeoutRef</code>). Refs aren't just for DOM nodes—they're perfect for any mutable value that shouldn't cause re-renders.</p>
<p><strong>3. Optional Chaining</strong></p>
<pre><code class="lang-javascript">inputRef.current?.focus();
</code></pre>
<p>Using <code>?.</code> ensures we don't throw an error if the ref is null.</p>
<h2 id="heading-common-dom-operations-with-useref">Common DOM Operations with useRef</h2>
<h3 id="heading-measuring-elements">Measuring Elements</h3>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ImageGallery</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> containerRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [dimensions, setDimensions] = useState({ <span class="hljs-attr">width</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">0</span> });

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (containerRef.current) {
      <span class="hljs-keyword">const</span> { width, height } = containerRef.current.getBoundingClientRect();
      setDimensions({ width, height });
    }
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{containerRef}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Container size: {dimensions.width}x{dimensions.height}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-scrolling-to-elements">Scrolling to Elements</h3>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChatWindow</span>(<span class="hljs-params">{ messages }</span>) </span>{
  <span class="hljs-keyword">const</span> bottomRef = useRef(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Scroll to bottom when new messages arrive</span>
    bottomRef.current?.scrollIntoView({ <span class="hljs-attr">behavior</span>: <span class="hljs-string">'smooth'</span> });
  }, [messages]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"chat-messages"</span>&gt;</span>
      {messages.map(msg =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{msg.id}</span>&gt;</span>{msg.text}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      ))}
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{bottomRef}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-playingpausing-media">Playing/Pausing Media</h3>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">VideoPlayer</span>(<span class="hljs-params">{ src }</span>) </span>{
  <span class="hljs-keyword">const</span> videoRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isPlaying, setIsPlaying] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> togglePlay = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (videoRef.current) {
      <span class="hljs-keyword">if</span> (isPlaying) {
        videoRef.current.pause();
      } <span class="hljs-keyword">else</span> {
        videoRef.current.play();
      }
      setIsPlaying(!isPlaying);
    }
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">video</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{videoRef}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{src}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{togglePlay}</span>&gt;</span>
        {isPlaying ? 'Pause' : 'Play'}
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-best-practices">Best Practices</h2>
<h3 id="heading-1-always-check-for-null">1. Always Check for Null</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Good</span>
<span class="hljs-keyword">if</span> (inputRef.current) {
  inputRef.current.focus();
}

<span class="hljs-comment">// Better</span>
inputRef.current?.focus();

<span class="hljs-comment">// Bad - can throw error</span>
inputRef.current.focus();
</code></pre>
<h3 id="heading-2-dont-overuse-refs">2. Don't Overuse Refs</h3>
<p>Use refs only when you need to step outside React's declarative paradigm. For most UI updates, state and props are the right choice.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Bad - using ref for something state should handle</span>
<span class="hljs-keyword">const</span> countRef = useRef(<span class="hljs-number">0</span>);
countRef.current += <span class="hljs-number">1</span>; <span class="hljs-comment">// Won't trigger re-render</span>

<span class="hljs-comment">// Good - use state for values that affect rendering</span>
<span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
setCount(<span class="hljs-function"><span class="hljs-params">c</span> =&gt;</span> c + <span class="hljs-number">1</span>); <span class="hljs-comment">// Triggers re-render</span>
</code></pre>
<h3 id="heading-3-clean-up-side-effects">3. Clean Up Side Effects</h3>
<p>When using refs with timers, event listeners, or subscriptions, always clean them up.</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> element = elementRef.current;

  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'clicked'</span>);
  element?.addEventListener(<span class="hljs-string">'click'</span>, handleClick);

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    element?.removeEventListener(<span class="hljs-string">'click'</span>, handleClick);
  };
}, []);
</code></pre>
<h3 id="heading-4-use-typescript-for-type-safety">4. Use TypeScript for Type Safety</h3>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> inputRef = useRef&lt;HTMLInputElement&gt;(<span class="hljs-literal">null</span>);
<span class="hljs-keyword">const</span> videoRef = useRef&lt;HTMLVideoElement&gt;(<span class="hljs-literal">null</span>);
<span class="hljs-keyword">const</span> divRef = useRef&lt;HTMLDivElement&gt;(<span class="hljs-literal">null</span>);
</code></pre>
<h2 id="heading-common-pitfalls-to-avoid">Common Pitfalls to Avoid</h2>
<h3 id="heading-pitfall-1-accessing-refs-during-render">Pitfall 1: Accessing Refs During Render</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Bad - don't access ref.current during render</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> ref = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-built_in">console</span>.log(ref.current); <span class="hljs-comment">// Will be null on first render</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span>&gt;</span>Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}

<span class="hljs-comment">// Good - access in useEffect or event handlers</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> ref = useRef(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(ref.current); <span class="hljs-comment">// Now it's safe</span>
  }, []);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span>&gt;</span>Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<h3 id="heading-pitfall-2-forgetting-dependencies">Pitfall 2: Forgetting Dependencies</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Bad - missing dependency</span>
useEffect(<span class="hljs-function">() =&gt;</span> {
  inputRef.current?.focus();
}, []); <span class="hljs-comment">// If inputRef comes from props, this is wrong</span>

<span class="hljs-comment">// Good - include all dependencies</span>
useEffect(<span class="hljs-function">() =&gt;</span> {
  inputRef.current?.focus();
}, [inputRef]);
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The <code>useRef</code> hook is a powerful tool for accessing DOM nodes in React. Remember these key points:</p>
<ul>
<li><p>Use <code>useRef</code> when you need direct DOM access</p>
</li>
<li><p>Always check if <code>ref.current</code> exists before using it</p>
</li>
<li><p>Access refs in <code>useEffect</code> or event handlers, not during render</p>
</li>
<li><p>Clean up any side effects that use refs</p>
</li>
<li><p>Prefer state for values that should trigger re-renders</p>
</li>
</ul>
<p>With these patterns, you're ready to handle DOM manipulation confidently in your React applications.</p>
<hr />
<p><strong>Further Reading:</strong></p>
<ul>
<li><p><a target="_blank" href="https://react.dev/reference/react/useRef">React useRef Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://react.dev/learn/manipulating-the-dom-with-refs">Manipulating the DOM with Refs</a></p>
</li>
<li><p><a target="_blank" href="https://react.dev/learn/referencing-values-with-refs">Understanding React Refs</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Design Consistent Hashing]]></title><description><![CDATA[Consistent hashing is a technique in distributed systems that maps data keys and servers to a conceptual "hash ring," minimizing data remapping when nodes are added or removed, ensuring stability and efficient load balancing by only reassigning a fra...]]></description><link>https://yashrajxdev.blog/design-consistent-hashing</link><guid isPermaLink="true">https://yashrajxdev.blog/design-consistent-hashing</guid><category><![CDATA[System Design]]></category><category><![CDATA[System Architecture]]></category><category><![CDATA[Redis]]></category><category><![CDATA[caching]]></category><category><![CDATA[Databases]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[Cassandra]]></category><category><![CDATA[Azure]]></category><category><![CDATA[akamai]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 17 Jan 2026 18:11:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768673027863/77f76614-26ff-4a8a-bef5-438611fc65e9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Consistent hashing is <strong>a technique in distributed systems that maps data keys and servers to a conceptual "hash ring," <mark>minimizing data remapping</mark> when nodes are added or removed, ensuring stability and efficient load balancing by only reassigning a fraction of keys</strong>, unlike traditional hashing. It works by placing servers and data points on this ring, then assigning data to the next server clockwise, making it ideal for databases (Cassandra), CDNs (Akamai), and distributed caches.</p>
<p>First,</p>
<p><strong>What is key ?</strong></p>
<p>A key is any <strong>identifier</strong> that:</p>
<ol>
<li><p>Uniquely represents a piece of data or request</p>
</li>
<li><p>Needs to be consistently routed to the same node</p>
</li>
<li><p>Can be hashed to produce a number</p>
</li>
</ol>
<hr />
<h2 id="heading-why-consistent-hashing-exists">Why consistent hashing exists?</h2>
<p><strong>The problem it solves:</strong></p>
<p>Traditional hashing uses: <code>server = hash(key) % number_of_servers</code></p>
<p>Example with 4 servers:</p>
<ul>
<li><p><code>hash("user:123") % 4 = 2</code> → Server 2</p>
</li>
<li><p><code>hash("user:456") % 4 = 1</code> → Server 1</p>
</li>
</ul>
<p><strong>What breaks:</strong></p>
<p>When you add/remove a server (say go from 4 to 5 servers):</p>
<ul>
<li><p><code>hash("user:123") % 5 = 3</code> → Now Server 3 (was Server 2!)</p>
</li>
<li><p><code>hash("user:456") % 5 = 1</code> → Still Server 1 (lucky!)</p>
</li>
</ul>
<p><strong>Result:</strong> Almost every key gets remapped to a different server because the modulo divisor changed. If you have 1 million cached items, adding one server means <mark>~800,000+ cache</mark> misses and data movement.</p>
<p><strong>Consistent hashing fixes this:</strong></p>
<p>When adding/removing servers, only <strong><mark>~K/N keys</mark></strong> need remapping (where K = total keys, N = number of servers).</p>
<ul>
<li><p>Add a server: ~1/N keys move</p>
</li>
<li><p>Remove a server: only that server's keys move</p>
</li>
</ul>
<p><strong>Real-world impact:</strong></p>
<p>Without consistent hashing:</p>
<ul>
<li><p>Adding a cache server → entire cache invalidated → database meltdown</p>
</li>
<li><p>Server failure → all keys remapped → cascading failures</p>
</li>
</ul>
<p>With consistent hashing:</p>
<ul>
<li><p>Adding a cache server → smooth, minimal disruption</p>
</li>
<li><p>Server failure → only affected keys redistributed</p>
</li>
</ul>
<p><strong>Bottom line:</strong> It enables elastic scaling in distributed systems without causing massive data shuffles that would overwhelm your infrastructure.</p>
<hr />
<h2 id="heading-how-it-works"><strong>How it works</strong></h2>
<ol>
<li><p><strong>Hash Ring Creation</strong>: A large, circular hash space (the "ring") is defined, using a hash function (like MD5) for both servers and data keys.</p>
</li>
<li><p><strong>Node Placement</strong>: Each server (or node) is hashed and placed at a specific point on the ring, often using multiple virtual points for better distribution.</p>
</li>
<li><p><strong>Data Mapping</strong>: Data keys are also hashed, placing them on the ring.</p>
</li>
<li><p><strong>Assignment</strong>: A data key is assigned to the first server encountered when moving clockwise from the key's position on the ring.</p>
</li>
</ol>
<p><strong>Common enhancement:</strong></p>
<p>Systems often use "virtual nodes"—each physical server gets multiple positions on the ring. This distributes load more evenly and prevents hotspots when servers have different capacities.</p>
<p><strong>Real-world uses:</strong></p>
<p>Distributed caches (Memcached, Redis clusters), distributed databases (Cassandra, DynamoDB), and content delivery networks all use consistent hashing to efficiently distribute data across changing sets of servers.</p>
<p><strong>The problem without virtual nodes:</strong></p>
<p>Imagine you have 3 servers on the hash ring. With simple consistent hashing, each server appears once on the ring at a random position. You might end up with:</p>
<pre><code class="lang-plaintext">Server A: position 100
Server B: position 200  
Server C: position 500
</code></pre>
<p>This creates uneven ranges:</p>
<ul>
<li><p>Server A handles keys from 500→100 (a huge arc of ~600 units)</p>
</li>
<li><p>Server B handles keys from 100→200 (only 100 units)</p>
</li>
<li><p>Server C handles keys from 200→500 (300 units)</p>
</li>
</ul>
<p>Server A gets 6x more load than Server B—very unbalanced!</p>
<p><strong>The solution with virtual nodes:</strong></p>
<p>Instead of placing each server once, you create multiple "virtual" copies. Say 150 virtual nodes per physical server:</p>
<pre><code class="lang-plaintext">Server A: positions 45, 123, 289, 467, 891, ... (150 positions total)
Server B: positions 12, 234, 356, 678, 923, ... (150 positions total)
Server C: positions 78, 145, 401, 567, 834, ... (150 positions total)
</code></pre>
<p>Now the ring has 450 points instead of 3, and they're scattered throughout. This means:</p>
<ul>
<li><p>Each server's ranges are distributed across the entire ring</p>
</li>
<li><p>Load averages out statistically—each server handles roughly 33% of keys</p>
</li>
<li><p>When a server fails, its load redistributes evenly across remaining servers</p>
</li>
</ul>
<hr />
<h2 id="heading-how-this-virtual-nodes-are-placed-in-ring">How this virtual nodes are placed in ring ?</h2>
<p>The placement of virtual nodes uses <strong><mark>hash functions</mark></strong> to generate their positions on the ring.</p>
<p>For each physical server, you generate multiple virtual node identifiers and hash them:</p>
<pre><code class="lang-plaintext">Server A, Virtual Node 0: hash("ServerA-0") → position 12847
Server A, Virtual Node 1: hash("ServerA-1") → position 98234
Server A, Virtual Node 2: hash("ServerA-2") → position 45621
...
Server A, Virtual Node 149: hash("ServerA-149") → position 73012
</code></pre>
<p><strong>Common patterns:</strong></p>
<ol>
<li><p><strong>Append index</strong>: <code>hash(serverID + index)</code></p>
<ul>
<li>Example: <code>hash("192.168.1.10-0")</code>, <code>hash("192.168.1.10-1")</code></li>
</ul>
</li>
<li><p><strong>Random seeds</strong>: Use different hash functions or seeds</p>
<ul>
<li>Example: <code>MD5(serverID + vnodeNumber)</code></li>
</ul>
</li>
<li><p><strong>Multiple hash functions</strong>: Apply different hashes to the same server ID</p>
<ul>
<li>Example: <code>SHA1(serverID)</code>, <code>MD5(serverID)</code>, <code>CRC32(serverID)</code></li>
</ul>
</li>
</ol>
<p><strong>Key properties:</strong></p>
<ul>
<li><p>The hash function produces <strong>pseudo-random</strong> but <strong>deterministic</strong> positions</p>
</li>
<li><p>Positions are uniformly distributed across the ring (0 to 2^32 or similar)</p>
</li>
<li><p>Same server always gets the same virtual node positions (deterministic)</p>
</li>
<li><p>Different servers get different positions (good hash distribution)</p>
</li>
</ul>
<p><strong>Data structure:</strong></p>
<p>In practice, you maintain a sorted list or tree of all virtual node positions:</p>
<pre><code class="lang-plaintext">[12847 → Server A, 23456 → Server C, 45621 → Server A, 67890 → Server B, ...]
</code></pre>
<p>When a key needs placement, you hash it and do a binary search to find the next position clockwise—that's the responsible server.</p>
<hr />
<h2 id="heading-real-world-example-of-how-a-request-flows-through-a-consistent-hashing-system">Real-world example of how a request flows through a consistent hashing system</h2>
<p><strong>Scenario: Distributed Cache (like Memcached cluster)</strong></p>
<p>You have 3 cache servers with 3 virtual nodes each:</p>
<pre><code class="lang-plaintext">Hash Ring (0 to 999 for simplicity):
Position 045 → Server A (vnode 0)
Position 123 → Server B (vnode 0)
Position 234 → Server C (vnode 0)
Position 456 → Server A (vnode 1)
Position 567 → Server B (vnode 1)
Position 678 → Server C (vnode 1)
Position 789 → Server A (vnode 2)
Position 890 → Server B (vnode 2)
Position 912 → Server C (vnode 2)
</code></pre>
<p><strong>Request comes in:</strong></p>
<p>A user requests: <code>GET user:12345:profile</code></p>
<p><strong>Step-by-step:</strong></p>
<ol>
<li><p><strong>Hash the key:</strong> <code>hash("user:12345:profile") → 500</code></p>
</li>
<li><p><strong>Find position on ring:</strong> Looking at position 500, search clockwise for the next server: <code>... 456 (Server A) &lt; 500 &lt; 567 (Server B) ...</code></p>
</li>
</ol>
<p>The next position clockwise is <strong>567 → Server B</strong></p>
<ol start="3">
<li><strong>Route to Server B:</strong> Request goes to Server B (192.168.1.20):</li>
</ol>
<p><code>Client → Load Balancer → Server B</code></p>
<ol start="4">
<li><p>Server B handles it</p>
<ul>
<li><p>If data exists: return from cache</p>
</li>
<li><p>If miss: fetch from database, cache it, return to client</p>
</li>
</ul>
</li>
</ol>
<p><strong>Another request:</strong></p>
<p><code>GET user:99999:profile</code></p>
<ol>
<li><p><code>hash("user:99999:profile") → 800</code></p>
</li>
<li><p>Next position clockwise: 890 → <strong>Server B</strong></p>
</li>
<li><p>Route to Server B again</p>
</li>
</ol>
<p><strong>Third request:</strong></p>
<p><code>GET user:55555:profile</code></p>
<ol>
<li><p><code>hash("user:55555:profile") → 100</code></p>
</li>
<li><p>Next position clockwise: 123 → <strong>Server B</strong></p>
</li>
<li><p>Route to Server B</p>
</li>
</ol>
<p><strong>Fourth request:</strong></p>
<p><code>GET product:88888:details</code></p>
<ol>
<li><p><code>hash("product:88888:details") → 950</code></p>
</li>
<li><p>Next position clockwise: wrap around to 045 → <strong>Server A</strong></p>
</li>
<li><p>Route to Server A</p>
</li>
</ol>
<h3 id="heading-what-happens-when-server-c-fails">What happens when Server C fails?</h3>
<p>Ring becomes:</p>
<pre><code class="lang-plaintext">Position 045 → Server A
Position 123 → Server B
Position 456 → Server A
Position 567 → Server B
Position 789 → Server A
Position 890 → Server B
(Server C's positions removed)
</code></pre>
<p>Keys that were on Server C (positions 234, 678, 912) now redistribute:</p>
<ul>
<li><p>Keys near 234 → go to Server A (position 456)</p>
</li>
<li><p>Keys near 678 → go to Server A (position 789)</p>
</li>
<li><p>Keys near 912 → go to Server A (position 045)</p>
</li>
</ul>
<p>Only <mark>~33%</mark> of keys are remapped (those that were on Server C), not the entire dataset!</p>
]]></content:encoded></item><item><title><![CDATA[useEffect in React.js [part-3]]]></title><description><![CDATA[Understanding cleanup functions in React's useEffect hook is crucial for building robust, production-ready applications. While effects without cleanup may appear to work initially, they can lead to serious performance degradation, memory leaks, and u...]]></description><link>https://yashrajxdev.blog/useeffect-in-reactjs-part-3</link><guid isPermaLink="true">https://yashrajxdev.blog/useeffect-in-reactjs-part-3</guid><category><![CDATA[React]]></category><category><![CDATA[React Native]]></category><category><![CDATA[Angular]]></category><category><![CDATA[tanstack]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Java]]></category><category><![CDATA[Full Stack Development]]></category><category><![CDATA[software development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[CSS]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 10 Jan 2026 14:14:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136363448/6aec51c9-8c03-4a13-ab18-d2379e7220a6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Understanding cleanup functions in React's useEffect hook is crucial for building robust, production-ready applications. While effects without cleanup may appear to work initially, they can lead to <strong>serious performance degradation, memory leaks, and unexpected behavior</strong> in real-world scenarios.</p>
<p>The <code>useEffect</code> cleanup function is an optional function you can return from within the <code>useEffect</code> Hook that handles the cleanup of side effects to prevent memory leaks and unwanted behavior in your application.</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Setup the side effect</span>
    <span class="hljs-keyword">const</span> intervalId = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      setCount(<span class="hljs-function"><span class="hljs-params">c</span> =&gt;</span> c + <span class="hljs-number">1</span>);
    }, <span class="hljs-number">1000</span>);

    <span class="hljs-comment">// Return the cleanup function</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">clearInterval</span>(intervalId); <span class="hljs-comment">// Tidy up the interval</span>
    };
  }, []); <span class="hljs-comment">// Empty dependency array means it runs on mount and cleans up on unmount</span>
</code></pre>
<p>The cleanup function should <strong><em>stop or undo whatever the setup function was doing</em></strong>.</p>
<p><strong>Purpose and When It Runs</strong></p>
<p>It runs in two main scenarios:</p>
<ul>
<li><p><strong><mark>Before the component unmounts</mark></strong> (removed from the DOM).</p>
</li>
<li><p><strong><mark>Before the effect runs again</mark></strong> due to a change in its dependencies.</p>
</li>
</ul>
<p>This ensures that the previous effect is tidied up before a new one is initiated, preventing issues like trying to update the state of an unmounted component or having multiple intervals running simultaneously. It is very important to clean up to prevent unwanted issues at production grade application.</p>
<h2 id="heading-the-problem-resource-leaks-in-component-lifecycles">The Problem: Resource Leaks in Component Lifecycles</h2>
<p>Consider a real-time dashboard that displays user activity data. The component fetches updates every 5 seconds using a polling mechanism:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserActivityDashboard</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [activities, setActivities] = useState([]);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> interval = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      fetchUserActivities().then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
        setActivities(data);
      });
    }, <span class="hljs-number">5000</span>);
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {activities.map(activity =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">ActivityCard</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{activity.id}</span> {<span class="hljs-attr">...activity</span>} /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>The Critical Flaw:</strong> When this component unmounts (user navigates away), the interval continues executing in the background. Each time the user returns to the dashboard, a new interval is created without clearing the previous one. Since this browser APIs are outside of react control it will be keep running even though component is not present on page, react knows that but browser does not.</p>
<h3 id="heading-consequences-without-cleanup"><strong>Consequences Without Cleanup:</strong></h3>
<ul>
<li><p>Multiple intervals run simultaneously, multiplying API requests</p>
</li>
<li><p>Server load increases exponentially with each component mount/unmount cycle</p>
</li>
<li><p>Memory consumption grows continuously as abandoned intervals accumulate</p>
</li>
<li><p>State updates may be attempted on unmounted components, triggering React warnings</p>
</li>
<li><p>API rate limits may be exceeded, causing service degradation</p>
</li>
<li><p>Increased infrastructure costs from unnecessary network traffic</p>
</li>
</ul>
<h2 id="heading-the-solution-implementing-cleanup-functions">The Solution: Implementing Cleanup Functions</h2>
<p>The cleanup function returned from useEffect executes when the component unmounts or before the effect runs again, ensuring proper resource disposal:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserActivityDashboard</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [activities, setActivities] = useState([]);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> interval = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      fetchUserActivities().then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
        setActivities(data);
      });
    }, <span class="hljs-number">5000</span>);

    <span class="hljs-comment">// Cleanup function - runs on unmount</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">clearInterval</span>(interval);
    };
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {activities.map(activity =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">ActivityCard</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{activity.id}</span> {<span class="hljs-attr">...activity</span>} /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>The cleanup function ensures that when the component unmounts, the interval is properly cleared, preventing the accumulation of background processes.</p>
<h2 id="heading-common-scenarios-requiring-cleanup">Common Scenarios Requiring Cleanup</h2>
<h3 id="heading-1-websocket-connections">1. WebSocket Connections</h3>
<p>WebSocket connections maintain persistent, bidirectional communication channels between client and server:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> ws = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">'wss://api.example.com/live'</span>);

  ws.onmessage = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    setMessages(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> [...prev, event.data]);
  };

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    ws.close();
  };
}, []);
</code></pre>
<p><strong>What This Does:</strong> The effect establishes a WebSocket connection and registers a message handler. When messages arrive from the server, they're added to the existing messages array using the functional form of setState (<code>prev =&gt; [...prev,</code> <code>event.data]</code>), which ensures we're working with the most current state.</p>
<p><strong>Consequences Without Cleanup:</strong></p>
<ul>
<li><p>Socket connections remain open indefinitely, consuming server resources</p>
</li>
<li><p>The server continues sending messages to disconnected clients</p>
</li>
<li><p>Multiple socket connections accumulate for the same user session</p>
</li>
<li><p>Message handlers attempt to update state on unmounted components</p>
</li>
<li><p>Server-side connection limits may be reached, affecting all users</p>
</li>
<li><p>Memory leaks occur from retained message handlers and accumulated data</p>
</li>
<li><p>Network bandwidth is wasted on messages sent to inactive connections</p>
</li>
</ul>
<hr />
<h3 id="heading-2-event-listeners">2. Event Listeners</h3>
<p>DOM event listeners attach handlers to global objects like window or document:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> handleResize = <span class="hljs-function">() =&gt;</span> {
    setWindowWidth(<span class="hljs-built_in">window</span>.innerWidth);
  };

  <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'resize'</span>, handleResize);

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'resize'</span>, handleResize);
  };
}, []);
</code></pre>
<p><strong>What This Does:</strong> The effect registers a resize event listener on the window object. The handler captures the current window width and updates component state. The cleanup function removes the listener when the component unmounts.</p>
<p><strong>Consequences Without Cleanup:</strong></p>
<ul>
<li><p>Event listeners accumulate with each component mount, creating duplicates</p>
</li>
<li><p>All registered handlers execute on every event, causing redundant processing</p>
</li>
<li><p>Memory leaks occur as handlers maintain references to unmounted components</p>
</li>
<li><p>Performance degrades as the number of active listeners grows</p>
</li>
<li><p>setState calls on unmounted components trigger console warnings</p>
</li>
<li><p>Browser DevTools show increasing numbers of event listeners over time</p>
</li>
<li><p>Application responsiveness decreases due to excessive event handling</p>
</li>
</ul>
<hr />
<h3 id="heading-3-asynchronous-operations-with-state-updates">3. Asynchronous Operations with State Updates</h3>
<p>Async operations may complete after a component has unmounted, attempting to update non-existent state:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">let</span> isCancelled = <span class="hljs-literal">false</span>;

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadUser</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchUser(userId);
    <span class="hljs-keyword">if</span> (!isCancelled) {
      setUser(user);
    }
  }

  loadUser();

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    isCancelled = <span class="hljs-literal">true</span>;
  };
}, [userId]);
</code></pre>
<p><strong>What This Does:</strong> The effect initiates an async data fetch and uses a cancellation flag to track whether the component is still mounted. The cleanup function sets this flag to true, preventing state updates if the fetch completes after unmounting. When <code>userId</code> changes, the cleanup runs before the new effect, canceling the previous request.</p>
<p><strong>Consequences Without Cleanup:</strong></p>
<ul>
<li><p>React warnings: "Can't perform a React state update on an unmounted component"</p>
</li>
<li><p>Race conditions where older requests overwrite newer data</p>
</li>
<li><p>Unnecessary network requests continue processing despite irrelevant results</p>
</li>
<li><p>Memory isn't freed properly as callbacks hold references to unmounted components</p>
</li>
<li><p>Application state becomes inconsistent when stale data overwrites current state</p>
</li>
<li><p>Debugging becomes difficult due to non-deterministic state updates</p>
</li>
<li><p>User experience suffers from UI flickering as outdated data briefly appears</p>
</li>
</ul>
<hr />
<h3 id="heading-4-subscriptions-eg-firebase-redux">4. Subscriptions (e.g., Firebase, Redux)</h3>
<p>External data subscriptions require explicit unsubscription to prevent leaks:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> unsubscribe = firestore
    .collection(<span class="hljs-string">'messages'</span>)
    .onSnapshot(<span class="hljs-function"><span class="hljs-params">snapshot</span> =&gt;</span> {
      <span class="hljs-keyword">const</span> messages = snapshot.docs.map(<span class="hljs-function"><span class="hljs-params">doc</span> =&gt;</span> ({
        <span class="hljs-attr">id</span>: doc.id,
        ...doc.data()
      }));
      setMessages(messages);
    });

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    unsubscribe();
  };
}, []);
</code></pre>
<p><strong>What This Does:</strong> The effect creates a real-time subscription to a Firestore collection. The <code>onSnapshot</code> method returns an unsubscribe function, which we store and call during cleanup to terminate the subscription.</p>
<p><strong>Consequences Without Cleanup:</strong></p>
<ul>
<li><p>Active subscriptions continue consuming backend resources</p>
</li>
<li><p>Real-time updates trigger state changes on unmounted components</p>
</li>
<li><p>Database read operations continue, increasing billing costs</p>
</li>
<li><p>Multiple subscriptions to the same data source accumulate</p>
</li>
<li><p>Server maintains unnecessary open connections</p>
</li>
<li><p>Memory leaks from retained snapshot listeners and callbacks</p>
</li>
<li><p>Network bandwidth wasted on updates for inactive UI components</p>
</li>
</ul>
<hr />
<h3 id="heading-5-animation-frames">5. Animation Frames</h3>
<p>RequestAnimationFrame creates render loops that must be canceled:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">let</span> animationId;

  <span class="hljs-keyword">const</span> animate = <span class="hljs-function">() =&gt;</span> {
    setPosition(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> ({
      <span class="hljs-attr">x</span>: prev.x + velocity.x,
      <span class="hljs-attr">y</span>: prev.y + velocity.y
    }));
    animationId = requestAnimationFrame(animate);
  };

  animationId = requestAnimationFrame(animate);

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    cancelAnimationFrame(animationId);
  };
}, [velocity.x, velocity.y]);
</code></pre>
<p><strong>What This Does:</strong> The effect creates a recursive animation loop using requestAnimationFrame, updating position on every frame. The cleanup function cancels any pending animation frame when the component unmounts or when velocity dependencies change.</p>
<p><strong>Consequences Without Cleanup:</strong></p>
<ul>
<li><p>Animation loops continue running invisibly in the background</p>
</li>
<li><p>CPU usage remains high even when animations aren't visible</p>
</li>
<li><p>Battery drain on mobile devices due to constant rendering</p>
</li>
<li><p>Multiple animation loops run simultaneously, compounding performance issues</p>
</li>
<li><p>Frame rate decreases as orphaned animations accumulate</p>
</li>
<li><p>Browser becomes unresponsive under the load of hundreds of animation frames</p>
</li>
<li><p>Thermal throttling may occur on devices from sustained high CPU usage</p>
</li>
</ul>
<hr />
<h2 id="heading-best-practices">Best Practices</h2>
<p><strong>Rule of Principle:</strong> If an effect creates a resource, establishes a connection, registers a listener, or initiates an ongoing process, it must include cleanup logic. The cleanup function should reverse or terminate whatever the effect established.</p>
<p><strong>Testing Cleanup:</strong> In development, React's Strict Mode intentionally mounts components twice to expose missing cleanup logic. Effects without proper cleanup will exhibit doubled behavior, making issues immediately visible.</p>
<p><strong>Pattern Recognition:</strong> Look for these patterns that always require cleanup:</p>
<ul>
<li><p><code>setInterval</code> / <code>setTimeout</code> → <code>clearInterval</code> / <code>clearTimeout</code></p>
</li>
<li><p><code>addEventListener</code> → <code>removeEventListener</code></p>
</li>
<li><p><code>new WebSocket()</code> → <code>ws.close()</code></p>
</li>
<li><p><code>.subscribe()</code> → <code>.unsubscribe()</code> or returned unsubscribe function</p>
</li>
<li><p><code>requestAnimationFrame</code> → <code>cancelAnimationFrame</code></p>
</li>
<li><p>Async operations → cancellation flags or AbortController</p>
</li>
</ul>
<p>Proper cleanup ensures applications remain performant, predictable, and maintainable as they scale in complexity and user engagement.</p>
]]></content:encoded></item><item><title><![CDATA[useEffect in React.js [part-2]]]></title><description><![CDATA[What is need of useEffect ?
The need for useEffect in React is to handle side effects in functional components, allowing you to synchronize your component with an external system after rendering, preventing interference with the rendering process. It...]]></description><link>https://yashrajxdev.blog/useeffect-in-reactjs-part-2</link><guid isPermaLink="true">https://yashrajxdev.blog/useeffect-in-reactjs-part-2</guid><category><![CDATA[React]]></category><category><![CDATA[React Native]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[CSS]]></category><category><![CDATA[CSS3]]></category><category><![CDATA[CSS Animation]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[webdev]]></category><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[coding journey]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Fri, 09 Jan 2026 20:12:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136322433/04236624-814d-4955-b5f8-2d99227230d1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-what-is-need-of-useeffect"><strong>What is need of useEffect ?</strong></h3>
<p>The need for <code>useEffect</code> in React is <strong>to handle side effects</strong> in functional components, allowing you to synchronize your component with an external system <em>after</em> rendering, preventing interference with the rendering process. It manages tasks like data fetching, setting up subscriptions (timers, event listeners), and directly manipulating the DOM, replacing class component lifecycle methods (like <code>componentDidMount</code>, <code>componentDidUpdate</code>) with a unified API.</p>
<p><strong>What are Side Effects?</strong><br />Side effects are any actions that reach outside the component's scope to interact with something React doesn't directly control, such as:</p>
<ul>
<li><p><strong>Data Fetching:</strong> Calling APIs to get data.</p>
</li>
<li><p><strong>DOM Manipulation:</strong> Changing the document title or adding/removing elements.</p>
</li>
<li><p><strong>Subscriptions:</strong> Setting up timers (setTimeout, setInterval) or event listeners (window resize, keypress).</p>
</li>
<li><p><strong>Logging:</strong> Logging to the console.</p>
</li>
</ul>
<hr />
<h3 id="heading-what-problem-occurs-when-we-do-not-use-useeffect-for-side-effects"><strong>What problem occurs when we do not use useEffect for side effects ?</strong></h3>
<p><strong>Problem 1:</strong> Infinite Loops 💥</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BadComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-comment">// ❌ This runs DURING render</span>
  setCount(count + <span class="hljs-number">1</span>); <span class="hljs-comment">// This triggers a re-render</span>
                       <span class="hljs-comment">// Which runs setCount again</span>
                       <span class="hljs-comment">// Which triggers another re-render</span>
                       <span class="hljs-comment">// INFINITE LOOP!</span>

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>What happens:</strong></p>
<ul>
<li><p>Render starts → <code>setCount</code> called → triggers re-render →</p>
</li>
<li><p>New render starts → <code>setCount</code> called again → triggers re-render →</p>
</li>
<li><p><strong>CRASH!</strong> React stops after ~50 iterations to prevent browser freeze</p>
</li>
</ul>
<hr />
<p><strong>Problem 2:</strong> Unpredictable Behavior</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BadAPICall</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);

  <span class="hljs-comment">// ❌ API call during render</span>
  fetch(<span class="hljs-string">'/api/data'</span>)
    .then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json())
    .then(setData); <span class="hljs-comment">// When data arrives, triggers re-render</span>

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{data || 'Loading...'}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>What happens:</strong></p>
<ul>
<li><p>Initial render → fetch called (Request #1 sent)</p>
</li>
<li><p>Parent re-renders for some reason → BadAPICall renders again → fetch called (Request #2 sent)</p>
</li>
<li><p>User clicks button → BadAPICall renders → fetch called (Request #3 sent)</p>
</li>
<li><p><strong>Result:</strong> Dozens of unnecessary API calls! Your server gets hammered! 📡💥</p>
</li>
</ul>
<hr />
<p><strong>Problem 3:</strong> Race Conditions</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserProfile</span>(<span class="hljs-params">{ userId }</span>) </span>{
  <span class="hljs-keyword">const</span> [user, setUser] = useState(<span class="hljs-literal">null</span>);

  <span class="hljs-comment">// ❌ Fetch during render</span>
  fetch(<span class="hljs-string">`/api/users/<span class="hljs-subst">${userId}</span>`</span>)
    .then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json())
    .then(setUser);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{user?.name}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}

<span class="hljs-comment">// User changes from ID 1 → ID 5 quickly</span>
<span class="hljs-comment">// Request for user 1 sent (takes 500ms)</span>
<span class="hljs-comment">// Request for user 5 sent (takes 100ms)</span>
<span class="hljs-comment">// User 5 displays ✓</span>
<span class="hljs-comment">// Then user 1 response arrives and overwrites it ❌</span>
<span class="hljs-comment">// Wrong user shown!</span>
</code></pre>
<hr />
<h3 id="heading-reacts-rendering-process">React's Rendering Process</h3>
<p>Here's what React actually does during a render:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// React's internal process (simplified)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reactRenderProcess</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Phase 1: RENDER (Pure calculation)</span>
  <span class="hljs-keyword">const</span> virtualDOM = YourComponent(); <span class="hljs-comment">// Just calls your function</span>

  <span class="hljs-comment">// Phase 2: Compare with previous render</span>
  <span class="hljs-keyword">const</span> changes = compareVirtualDOMs(oldVirtualDOM, virtualDOM);

  <span class="hljs-comment">// Phase 3: COMMIT (Actually update the browser)</span>
  applyChangesToRealDOM(changes);

  <span class="hljs-comment">// Phase 4: Run effects</span>
  runAllUseEffects(); <span class="hljs-comment">// ← This is where side effects happen!</span>
}
</code></pre>
<p><strong>During Phase 1 (Render):</strong></p>
<ul>
<li><p>React might call your component <strong>multiple times</strong></p>
</li>
<li><p>React might <strong>throw away</strong> the result without committing it</p>
</li>
<li><p>React needs to be able to pause and resume</p>
</li>
<li><p><strong>This is why it must be <mark>pure!</mark></strong></p>
</li>
</ul>
<hr />
<h2 id="heading-simple-analogy">Simple Analogy 🎨</h2>
<p>Think of rendering like a painter <strong>planning</strong> a painting:</p>
<p><strong>During Rendering (Planning Phase):</strong></p>
<ul>
<li><p>"I'll paint a tree here, a house there..."</p>
</li>
<li><p>Just thinking and sketching</p>
</li>
<li><p>Might change mind and start over</p>
</li>
<li><p><strong>Don't order paint, don't call suppliers!</strong></p>
</li>
</ul>
<p><strong>After Rendering (Execution Phase - useEffect):</strong></p>
<ul>
<li><p>Plan is finalized</p>
</li>
<li><p>Painting is on the wall</p>
</li>
<li><p><strong>Now</strong> you can order more paint, call the client, post on social media</p>
</li>
<li><p>These are "side effects"</p>
</li>
</ul>
<p><strong>Summary: Why Not Update State During Rendering?</strong></p>
<ol>
<li><p><strong>Renders can happen multiple times</strong> - React might render but not commit</p>
</li>
<li><p><strong>Renders must be predictable</strong> - <mark>Same input = same output</mark></p>
</li>
<li><p><strong>Prevents infinite loops</strong> - State updates during render cause re-renders</p>
</li>
<li><p><strong>Avoids duplicate side effects</strong> - API calls, subscriptions would run repeatedly</p>
</li>
<li><p><strong>Enables React features</strong> - Concurrent rendering, Suspense, time-slicing</p>
</li>
</ol>
<p><strong>The rule:</strong> Rendering = pure calculation. Side effects = useEffect.</p>
]]></content:encoded></item><item><title><![CDATA[useEffect in React.js [part-1]]]></title><description><![CDATA[Introduction
The useEffect hook in React lets you perform side effects in functional components, such as data fetching, subscriptions, or manually updating the DOM. It provides a way to synchronize your component with external systems after the rende...]]></description><link>https://yashrajxdev.blog/useeffect-in-reactjs-part-1</link><guid isPermaLink="true">https://yashrajxdev.blog/useeffect-in-reactjs-part-1</guid><category><![CDATA[React]]></category><category><![CDATA[React Native]]></category><category><![CDATA[useEffect]]></category><category><![CDATA[User Interface]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[web performance]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[HTML]]></category><category><![CDATA[CSS]]></category><category><![CDATA[CSS3]]></category><category><![CDATA[scss]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Mon, 05 Jan 2026 20:23:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136279391/2194a16c-590c-487c-ab8f-8f5c76be3984.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>The <code>useEffect</code> hook in React <strong>lets you perform side effects</strong> in functional components, such as data fetching, subscriptions, or manually updating the DOM. It provides a way to synchronize your component with external systems after the rendering process is complete.</p>
<p>In simple terms, when your component first renders and shows to the user, you often need to fetch fresh data from an API or set up event listeners. But here's the problem: you can't just make an API call and update a regular variable - React won't know anything changed, so it won't update what the user sees.</p>
<p>This is where useEffect comes in. It lets you run code <strong><em>after</em></strong> your component renders. Inside useEffect, you can fetch data and update state using setState. When you update state, React detects the change and re-renders your component with the new data.</p>
<p><strong>Think of it this way: useEffect is the designated place for 'side effects' - things like API calls, subscriptions, or timers that need to happen after rendering.</strong></p>
<hr />
<h3 id="heading-syntax"><strong>Syntax</strong></h3>
<ul>
<li><p><strong>Setup Function:</strong> Contains the core logic of your effect. React runs this function after the component renders and the DOM is updated.</p>
</li>
<li><p><strong>Cleanup Function (optional):</strong> If your effect needs cleanup (e.g., stopping a timer, unsubscribing from an event), you return a function from the setup function. React runs this cleanup function before the component unmounts or before the effect runs again due to a dependency change.</p>
</li>
<li><p><strong>Dependencies Array (optional):</strong> An array of values (props, state, etc.) that the effect depends on. The effect will re-run only when any value in this array changes.</p>
</li>
<li><p>Side effects are the ones which update the states.</p>
</li>
<li><p>Dependencies are the one when you want to run this side effects again when this dependency value is changed. It will run once if empty array is passed.</p>
</li>
</ul>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Side effect code (setup function)</span>

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Cleanup function (optional)</span>
  };
}, [dependencies]); <span class="hljs-comment">// Optional dependency array</span>
</code></pre>
<h3 id="heading-example">Example</h3>
<p>Basic but production level example used by many products and teams. Set window size when it is changed (resized). If you not able to understand it is fine just notice the syntax.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> WindowTracker = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// 1. Initialize state to hold the window width</span>
  <span class="hljs-keyword">const</span> [windowWidth, setWindowWidth] = useState(<span class="hljs-built_in">window</span>.innerWidth);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// 2. Define the function to update state</span>
    <span class="hljs-keyword">const</span> handleResize = <span class="hljs-function">() =&gt;</span> {
      setWindowWidth(<span class="hljs-built_in">window</span>.innerWidth);
    };

    <span class="hljs-comment">// 3. Setup: Add the event listener on mount</span>
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'resize'</span>, handleResize);

    <span class="hljs-comment">// 4. Cleanup: This function runs when the component is destroyed (unmounted)</span>
    <span class="hljs-comment">// In production, always clean up subscriptions, timers, and listeners!</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'resize'</span>, handleResize);
    };

    <span class="hljs-comment">// 5. Dependency Array: Empty [] means this effect runs ONCE on mount</span>
  }, []); 

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">padding:</span> '<span class="hljs-attr">20px</span>', <span class="hljs-attr">textAlign:</span> '<span class="hljs-attr">center</span>' }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Window Width Monitor<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>The current width of your browser is: <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{windowWidth}px<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> WindowTracker;
</code></pre>
<hr />
<p><strong>Common Use Cases</strong></p>
<ul>
<li><p><strong>Fetching Data:</strong> The most common use case is fetching data from an API when a component mounts or when a certain prop/state changes.</p>
</li>
<li><p><strong>DOM Manipulation:</strong> Manually updating the DOM (e.g., setting the document title) when this cannot be done declaratively in the render phase.</p>
</li>
<li><p><strong>Event Listeners/Subscriptions:</strong> Setting up and tearing down event listeners or subscriptions to external systems to prevent memory leaks.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[useState Hook in React [part-3]]]></title><description><![CDATA[State updates seem straightforward until they're not. Asynchronous operations, rapid user interactions, and event handlers create scenarios where your state updates reference stale values. Functional updates solve this elegantly, ensuring your state ...]]></description><link>https://yashrajxdev.blog/usestate-hook-in-react-part-3</link><guid isPermaLink="true">https://yashrajxdev.blog/usestate-hook-in-react-part-3</guid><category><![CDATA[React]]></category><category><![CDATA[React Native]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[CSS]]></category><category><![CDATA[scss]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Web3]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[Svelte]]></category><category><![CDATA[jQuery]]></category><category><![CDATA[UI]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Fri, 02 Jan 2026 17:42:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136231791/fb1f14b0-beed-4a9c-bde8-b7b14ef678de.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>State updates seem straightforward until they're not. Asynchronous operations, rapid user interactions, and event handlers create scenarios where your state updates reference stale values. Functional updates solve this elegantly, ensuring your state transformations always work with current data.</p>
<p>Understanding this small things can help in optimizing the code and creating bug less features. Everything matters at scale.</p>
<h2 id="heading-the-stale-state-problem">The Stale State Problem</h2>
<p>Consider this seemingly innocent counter:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BrokenCounter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> incrementThreeTimes = <span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
    setCount(count + <span class="hljs-number">1</span>);
    setCount(count + <span class="hljs-number">1</span>);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementThreeTimes}</span>&gt;</span>Add 3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>You expect the count to increase by 3. Instead, it increases by 1. Why? All three <code>setCount</code> calls capture the same <code>count</code> value from the render when the button was clicked. Each reads <code>count</code> as 0, resulting in three calls of <code>setCount(0 + 1)</code>.</p>
<h2 id="heading-functional-updates-the-solution">Functional Updates: The Solution</h2>
<p>Pass a function to your state setter instead of a value. React calls this function with the current state, guaranteeing you always work with up-to-date data:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ReliableCounter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> incrementThreeTimes = <span class="hljs-function">() =&gt;</span> {
    setCount(<span class="hljs-function"><span class="hljs-params">prevCount</span> =&gt;</span> prevCount + <span class="hljs-number">1</span>);
    setCount(<span class="hljs-function"><span class="hljs-params">prevCount</span> =&gt;</span> prevCount + <span class="hljs-number">1</span>);
    setCount(<span class="hljs-function"><span class="hljs-params">prevCount</span> =&gt;</span> prevCount + <span class="hljs-number">1</span>);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementThreeTimes}</span>&gt;</span>Add 3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Now each update receives the result of the previous update. The first call gets 0 and returns 1. The second call gets 1 and returns 2. The third call gets 2 and returns 3. Perfect.</p>
<hr />
<h2 id="heading-real-world-example-shopping-cart">Real-World Example: Shopping Cart</h2>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ShoppingCart</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [items, setItems] = useState([]);

  <span class="hljs-keyword">const</span> addItem = <span class="hljs-function">(<span class="hljs-params">product</span>) =&gt;</span> {
    setItems(<span class="hljs-function"><span class="hljs-params">prevItems</span> =&gt;</span> {
      <span class="hljs-keyword">const</span> existingItem = prevItems.find(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.id === product.id);

      <span class="hljs-keyword">if</span> (existingItem) {
        <span class="hljs-comment">// Increase quantity if item exists</span>
        <span class="hljs-keyword">return</span> prevItems.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span>
          item.id === product.id
            ? { ...item, <span class="hljs-attr">quantity</span>: item.quantity + <span class="hljs-number">1</span> }
            : item
        );
      }

      <span class="hljs-comment">// Add new item</span>
      <span class="hljs-keyword">return</span> [...prevItems, { ...product, <span class="hljs-attr">quantity</span>: <span class="hljs-number">1</span> }];
    });
  };

  <span class="hljs-keyword">const</span> removeItem = <span class="hljs-function">(<span class="hljs-params">productId</span>) =&gt;</span> {
    setItems(<span class="hljs-function"><span class="hljs-params">prevItems</span> =&gt;</span> prevItems.filter(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.id !== productId));
  };

  <span class="hljs-keyword">const</span> updateQuantity = <span class="hljs-function">(<span class="hljs-params">productId, newQuantity</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (newQuantity &lt;= <span class="hljs-number">0</span>) {
      removeItem(productId);
      <span class="hljs-keyword">return</span>;
    }

    setItems(<span class="hljs-function"><span class="hljs-params">prevItems</span> =&gt;</span>
      prevItems.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span>
        item.id === productId
          ? { ...item, <span class="hljs-attr">quantity</span>: newQuantity }
          : item
      )
    );
  };

  <span class="hljs-keyword">const</span> getTotalPrice = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> items.reduce(<span class="hljs-function">(<span class="hljs-params">total, item</span>) =&gt;</span> total + (item.price * item.quantity), <span class="hljs-number">0</span>);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"shopping-cart"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Shopping Cart<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      {items.length === 0 ? (
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Your cart is empty<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      ) : (
        <span class="hljs-tag">&lt;&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
            {items.map(item =&gt; (
              <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>${item.price}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                  <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span>
                  <span class="hljs-attr">value</span>=<span class="hljs-string">{item.quantity}</span>
                  <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> updateQuantity(item.id, parseInt(e.target.value))}
                  min="0"
                /&gt;
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> removeItem(item.id)}&gt;Remove<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
            ))}
          <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"cart-total"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>Total: ${getTotalPrice().toFixed(2)}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span></span>
      )}
    &lt;/div&gt;
  );
}
</code></pre>
<p>This cart uses functional updates throughout. The <code>addItem</code> function reads the previous items array to check if a product exists. Without functional updates, rapidly clicking "Add to Cart" could result in duplicate entries instead of increased quantities.</p>
<hr />
<h2 id="heading-asynchronous-operations-and-functional-updates">Asynchronous Operations and Functional Updates</h2>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AsyncCounter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> incrementAfterDelay = <span class="hljs-keyword">async</span> () =&gt; {
    setLoading(<span class="hljs-literal">true</span>);

    <span class="hljs-comment">// Simulate API call</span>
    <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

    <span class="hljs-comment">// Using functional update ensures we increment the current count</span>
    <span class="hljs-comment">// even if the user triggered multiple async operations</span>
    setCount(<span class="hljs-function"><span class="hljs-params">prevCount</span> =&gt;</span> prevCount + <span class="hljs-number">1</span>);
    setLoading(<span class="hljs-literal">false</span>);
  };

  <span class="hljs-keyword">const</span> incrementMultipleTimes = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Start 3 async operations simultaneously</span>
    incrementAfterDelay();
    incrementAfterDelay();
    incrementAfterDelay();
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{incrementMultipleTimes}</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{loading}</span>&gt;</span>
        Increment 3 Times (Async)
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      {loading &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Without functional updates, all three async operations would capture the initial <code>count</code> value, resulting in the counter only incrementing by 1 regardless of how many operations complete.</p>
<hr />
<h2 id="heading-production-pattern-todo-list-with-optimistic-updates">Production Pattern: Todo List with Optimistic Updates</h2>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TodoList</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [todos, setTodos] = useState([]);
  <span class="hljs-keyword">const</span> [inputValue, setInputValue] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> addTodo = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">if</span> (!inputValue.trim()) <span class="hljs-keyword">return</span>;

    <span class="hljs-keyword">const</span> tempId = <span class="hljs-built_in">Date</span>.now();
    <span class="hljs-keyword">const</span> newTodo = {
      <span class="hljs-attr">id</span>: tempId,
      <span class="hljs-attr">text</span>: inputValue,
      <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span>,
      <span class="hljs-attr">syncing</span>: <span class="hljs-literal">true</span>
    };

    <span class="hljs-comment">// Optimistic update</span>
    setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span> [...prevTodos, newTodo]);
    setInputValue(<span class="hljs-string">''</span>);

    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Simulate API call</span>
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'/api/todos'</span>, {
        <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
        <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">text</span>: newTodo.text }),
        <span class="hljs-attr">headers</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> }
      });

      <span class="hljs-keyword">const</span> savedTodo = <span class="hljs-keyword">await</span> response.json();

      <span class="hljs-comment">// Update with real ID from server</span>
      setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span>
        prevTodos.map(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span>
          todo.id === tempId
            ? { ...savedTodo, <span class="hljs-attr">syncing</span>: <span class="hljs-literal">false</span> }
            : todo
        )
      );
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// Rollback on error</span>
      setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span> prevTodos.filter(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> todo.id !== tempId));
      alert(<span class="hljs-string">'Failed to add todo'</span>);
    }
  };

  <span class="hljs-keyword">const</span> toggleTodo = <span class="hljs-keyword">async</span> (id) =&gt; {
    <span class="hljs-comment">// Optimistic update</span>
    setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span>
      prevTodos.map(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span>
        todo.id === id
          ? { ...todo, <span class="hljs-attr">completed</span>: !todo.completed, <span class="hljs-attr">syncing</span>: <span class="hljs-literal">true</span> }
          : todo
      )
    );

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/api/todos/<span class="hljs-subst">${id}</span>`</span>, {
        <span class="hljs-attr">method</span>: <span class="hljs-string">'PATCH'</span>,
        <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">completed</span>: <span class="hljs-literal">true</span> }),
        <span class="hljs-attr">headers</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> }
      });

      <span class="hljs-comment">// Remove syncing flag</span>
      setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span>
        prevTodos.map(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span>
          todo.id === id
            ? { ...todo, <span class="hljs-attr">syncing</span>: <span class="hljs-literal">false</span> }
            : todo
        )
      );
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// Rollback on error</span>
      setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span>
        prevTodos.map(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span>
          todo.id === id
            ? { ...todo, <span class="hljs-attr">completed</span>: !todo.completed, <span class="hljs-attr">syncing</span>: <span class="hljs-literal">false</span> }
            : todo
        )
      );
    }
  };

  <span class="hljs-keyword">const</span> deleteTodo = <span class="hljs-keyword">async</span> (id) =&gt; {
    <span class="hljs-keyword">const</span> todoToDelete = todos.find(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> todo.id === id);

    <span class="hljs-comment">// Optimistic delete</span>
    setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span> prevTodos.filter(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> todo.id !== id));

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/api/todos/<span class="hljs-subst">${id}</span>`</span>, { <span class="hljs-attr">method</span>: <span class="hljs-string">'DELETE'</span> });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// Rollback: add the todo back</span>
      setTodos(<span class="hljs-function"><span class="hljs-params">prevTodos</span> =&gt;</span> [...prevTodos, todoToDelete]);
      alert(<span class="hljs-string">'Failed to delete todo'</span>);
    }
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{inputValue}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setInputValue(e.target.value)}
        onKeyPress={(e) =&gt; e.key === 'Enter' &amp;&amp; addTodo()}
        placeholder="Add a todo..."
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{addTodo}</span>&gt;</span>Add<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {todos.map(todo =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{todo.id}</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">opacity:</span> <span class="hljs-attr">todo.syncing</span> ? <span class="hljs-attr">0.5</span> <span class="hljs-attr">:</span> <span class="hljs-attr">1</span> }}&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
              <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>
              <span class="hljs-attr">checked</span>=<span class="hljs-string">{todo.completed}</span>
              <span class="hljs-attr">onChange</span>=<span class="hljs-string">{()</span> =&gt;</span> toggleTodo(todo.id)}
              disabled={todo.syncing}
            /&gt;
            <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">textDecoration:</span> <span class="hljs-attr">todo.completed</span> ? '<span class="hljs-attr">line-through</span>' <span class="hljs-attr">:</span> '<span class="hljs-attr">none</span>' }}&gt;</span>
              {todo.text}
            <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> deleteTodo(todo.id)} disabled={todo.syncing}&gt;
              Delete
            <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>This code implements a React functional component for a <strong>To-Do List</strong> using a technique called <strong>Optimistic UI Updates</strong>. This pattern makes the app feel faster by updating the interface immediately before waiting for a server response.</p>
<h3 id="heading-key-functionalities">Key Functionalities</h3>
<ul>
<li><p><strong>Optimistic UI Strategy</strong>: For every action (add, toggle, delete), the app updates the local state <strong>first</strong> so the user sees the change instantly. It then makes the API call in the background and corrects the state only if the server fails.</p>
</li>
<li><p><strong>Syncing State</strong>: While a network request is in progress, the code sets a <code>syncing</code> flag. This is used to:</p>
<ul>
<li><p><strong>Visually dim</strong> the item (setting <code>opacity: 0.5</code>).</p>
</li>
<li><p><strong>Disable interactions</strong> (like clicking the checkbox or delete button) to prevent "race conditions" while the server is processing.</p>
</li>
</ul>
</li>
<li><p><strong>ID Management</strong>:</p>
<ul>
<li><p>When adding a task, it uses a <strong>temporary ID</strong> (<a target="_blank" href="http://Date.now"><code>Date.now</code></a><code>()</code>) to render the item immediately.</p>
</li>
<li><p>Once the server responds, it replaces the temporary ID with the <strong>permanent ID</strong> returned by the database.</p>
</li>
</ul>
</li>
<li><p><strong>Error Handling &amp; Rollbacks</strong>:</p>
<ul>
<li><p>If an API call fails, the <code>catch</code> blocks contain logic to <strong>revert</strong> the UI.</p>
</li>
<li><p>For example, if deleting fails, the item is added back to the list; if toggling fails, the checkbox switches back to its previous state.</p>
</li>
</ul>
</li>
</ul>
<p>With functional update this code works with integrity and consistency.</p>
<hr />
<h2 id="heading-when-to-use-functional-updates">When to use Functional Updates</h2>
<h3 id="heading-when-functional-updates-are-critical">When Functional Updates Are Critical</h3>
<p><strong>Multiple Updates in Single Event</strong>: Any time you update state multiple times in one function.</p>
<p><strong>Async Operations</strong>: setTimeout, setInterval, fetch calls, or any promise-based code.</p>
<p><strong>Event Handlers with Captured State</strong>: Callbacks that close over state values.</p>
<p><strong>Computed Updates</strong>: When the new state depends on the old state mathematically or logically.</p>
<h3 id="heading-when-direct-updates-work-fine">When Direct Updates Work Fine</h3>
<p><strong>Setting Absolute Values</strong>: When the new state doesn't depend on the old state:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> resetCount = <span class="hljs-function">() =&gt;</span> setCount(<span class="hljs-number">0</span>); <span class="hljs-comment">// Direct update is fine</span>
<span class="hljs-keyword">const</span> setToValue = <span class="hljs-function">(<span class="hljs-params">value</span>) =&gt;</span> setCount(value); <span class="hljs-comment">// Also fine</span>
</code></pre>
<p><strong>Single Update Per Event</strong>: If you only update state once per event and don't have async operations:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> {
  setCount(count + <span class="hljs-number">1</span>); <span class="hljs-comment">// Generally safe in isolation</span>
};
</code></pre>
<h3 id="heading-performance-characteristics">Performance Characteristics</h3>
<p>Functional updates don't add meaningful overhead. React must process the update regardless. The function call itself is <strong>negligible</strong> compared to the re-render cost.</p>
<p>React batches multiple state updates automatically in React 18+, whether using direct or functional updates. Batching optimizes renders, not individual state setter calls.</p>
<hr />
<h2 id="heading-common-patterns">Common Patterns</h2>
<p><strong>Toggle Boolean State</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [isOpen, setIsOpen] = useState(<span class="hljs-literal">false</span>);

<span class="hljs-comment">// Instead of: setIsOpen(!isOpen)</span>
<span class="hljs-keyword">const</span> toggle = <span class="hljs-function">() =&gt;</span> setIsOpen(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> !prev);
</code></pre>
<p><strong>Increment/Decrement</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> increment = <span class="hljs-function">() =&gt;</span> setCount(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev + <span class="hljs-number">1</span>);
<span class="hljs-keyword">const</span> decrement = <span class="hljs-function">() =&gt;</span> setCount(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev - <span class="hljs-number">1</span>);
<span class="hljs-keyword">const</span> incrementBy = <span class="hljs-function">(<span class="hljs-params">amount</span>) =&gt;</span> setCount(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev + amount);
</code></pre>
<p><strong>Array Operations</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Add item</span>
setItems(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> [...prev, newItem]);

<span class="hljs-comment">// Remove item</span>
setItems(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev.filter(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.id !== idToRemove));

<span class="hljs-comment">// Update item</span>
setItems(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> prev.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span>
  item.id === idToUpdate ? { ...item, ...updates } : item
));

<span class="hljs-comment">// Sort</span>
setItems(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> [...prev].sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a.value - b.value));
</code></pre>
<p><strong>Object Updates</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Merge properties</span>
setUser(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> ({ ...prev, <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span> }));

<span class="hljs-comment">// Nested update</span>
setSettings(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> ({
  ...prev,
  <span class="hljs-attr">preferences</span>: {
    ...prev.preferences,
    <span class="hljs-attr">theme</span>: <span class="hljs-string">'dark'</span>
  }
}));
</code></pre>
<hr />
<h2 id="heading-typescript-integration">TypeScript Integration</h2>
<pre><code class="lang-javascript">interface Todo {
  <span class="hljs-attr">id</span>: number;
  text: string;
  completed: boolean;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TypedTodoList</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [todos, setTodos] = useState&lt;Todo[]&gt;([]);

  <span class="hljs-keyword">const</span> addTodo = <span class="hljs-function">(<span class="hljs-params">text: string</span>) =&gt;</span> {
    setTodos(<span class="hljs-function">(<span class="hljs-params">prevTodos: Todo[]</span>) =&gt;</span> [
      ...prevTodos,
      { <span class="hljs-attr">id</span>: <span class="hljs-built_in">Date</span>.now(), text, <span class="hljs-attr">completed</span>: <span class="hljs-literal">false</span> }
    ]);
  };

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{/* UI */}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>TypeScript infers the parameter type automatically in most cases, but explicit typing clarifies intent.</p>
<hr />
<h2 id="heading-key-notes">Key Notes</h2>
<p><mark>Use functional updates when new state depends on previous state.</mark> This pattern prevents bugs in async operations, multiple updates, and event handlers with captured state.</p>
<p>The pattern is simple: pass a function instead of a value. React guarantees your function receives the current state, eliminating race conditions and stale closures.</p>
<p>Direct updates work perfectly when setting absolute values or making single updates without dependencies on previous state.</p>
]]></content:encoded></item><item><title><![CDATA[useState Hook in React [part-2]]]></title><description><![CDATA[Performance optimization often feels like premature optimization. But when initializing state requires expensive computations, lazy initialization becomes essential. This technique prevents unnecessary work on every render, executing initialization l...]]></description><link>https://yashrajxdev.blog/usestate-hook-in-react-part-2</link><guid isPermaLink="true">https://yashrajxdev.blog/usestate-hook-in-react-part-2</guid><category><![CDATA[React]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[HTML]]></category><category><![CDATA[CSS]]></category><category><![CDATA[CSS3]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[javascript framework]]></category><category><![CDATA[Javascript library]]></category><category><![CDATA[Angular]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[Java]]></category><category><![CDATA[Rust]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Thu, 01 Jan 2026 18:24:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136198307/278c48ba-6ce3-4bc4-aa8b-d024656749dc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Performance optimization often feels like premature optimization. But when initializing state requires expensive computations, lazy initialization becomes essential. This technique prevents unnecessary work on every render, <strong>executing initialization logic exactly once.</strong></p>
<h2 id="heading-the-problem-with-direct-initialization">The Problem with Direct Initialization</h2>
<p>Consider a component that initializes state from localStorage:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserPreferences</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// This runs on EVERY render</span>
  <span class="hljs-keyword">const</span> savedTheme = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'theme'</span>) || <span class="hljs-string">'{}'</span>);
  <span class="hljs-keyword">const</span> [preferences, setPreferences] = useState(savedTheme);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Theme: {preferences.mode}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>The localStorage read and JSON parsing execute on every render, even though useState only uses the initial value once. For a component that re-renders frequently, this wastes significant processing time.</p>
<h2 id="heading-lazy-initialization-function-based-initial-state">Lazy Initialization: Function-Based Initial State</h2>
<p>useState accepts a function as its initial value. React calls this function only during the initial render, <mark>skipping it on subsequent re-renders.</mark></p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">UserPreferences</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// This runs ONLY on the initial render</span>
  <span class="hljs-keyword">const</span> [preferences, setPreferences] = useState(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> saved = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'theme'</span>);
    <span class="hljs-keyword">return</span> saved ? <span class="hljs-built_in">JSON</span>.parse(saved) : { <span class="hljs-attr">mode</span>: <span class="hljs-string">'light'</span>, <span class="hljs-attr">fontSize</span>: <span class="hljs-number">16</span> };
  });

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Theme: {preferences.mode}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>The arrow function wraps the initialization logic. <strong>React invokes it once, <mark>caches</mark> the result, and ignores the function on future renders.</strong></p>
<h2 id="heading-real-world-use-case-complex-data-processing">Real-World Use Case: Complex Data Processing</h2>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DataAnalysisDashboard</span>(<span class="hljs-params">{ rawDataset }</span>) </span>{
  <span class="hljs-keyword">const</span> [processedData, setProcessedData] = useState(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Processing dataset...'</span>);

    <span class="hljs-comment">// Expensive operations</span>
    <span class="hljs-keyword">const</span> filtered = rawDataset.filter(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.isValid);
    <span class="hljs-keyword">const</span> sorted = filtered.sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> b.value - a.value);
    <span class="hljs-keyword">const</span> aggregated = sorted.reduce(<span class="hljs-function">(<span class="hljs-params">acc, item</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> key = item.category;
      acc[key] = (acc[key] || <span class="hljs-number">0</span>) + item.value;
      <span class="hljs-keyword">return</span> acc;
    }, {});

    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">items</span>: sorted.slice(<span class="hljs-number">0</span>, <span class="hljs-number">100</span>),
      <span class="hljs-attr">summary</span>: aggregated,
      <span class="hljs-attr">total</span>: filtered.length
    };
  });

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Analysis Results<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Total Items: {processedData.total}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {processedData.items.map(item =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.name}: {item.value}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Without lazy initialization, this filtering, sorting, and aggregation <strong><em>would execute on every render,</em></strong> degrading performance dramatically as the dataset grows.</p>
<h2 id="heading-production-pattern-form-with-persisted-state">Production Pattern: Form with Persisted State</h2>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AdvancedContactForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [formData, setFormData] = useState(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> saved = sessionStorage.getItem(<span class="hljs-string">'contactFormDraft'</span>);
      <span class="hljs-keyword">if</span> (saved) {
        <span class="hljs-keyword">const</span> parsed = <span class="hljs-built_in">JSON</span>.parse(saved);
        <span class="hljs-comment">// Validate the structure</span>
        <span class="hljs-keyword">if</span> (parsed.name &amp;&amp; parsed.email &amp;&amp; parsed.message) {
          <span class="hljs-keyword">return</span> parsed;
        }
      }
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Failed to load draft:'</span>, error);
    }

    <span class="hljs-comment">// Return default structure</span>
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>,
      <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>,
      <span class="hljs-attr">message</span>: <span class="hljs-string">''</span>,
      <span class="hljs-attr">subscribe</span>: <span class="hljs-literal">false</span>,
      <span class="hljs-attr">priority</span>: <span class="hljs-string">'normal'</span>
    };
  });

  <span class="hljs-keyword">const</span> updateField = <span class="hljs-function">(<span class="hljs-params">field, value</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> updated = { ...formData, [field]: value };
    setFormData(updated);

    <span class="hljs-comment">// Persist changes</span>
    sessionStorage.setItem(<span class="hljs-string">'contactFormDraft'</span>, <span class="hljs-built_in">JSON</span>.stringify(updated));
  };

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();
    <span class="hljs-comment">// Submit logic</span>
    sessionStorage.removeItem(<span class="hljs-string">'contactFormDraft'</span>);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{formData.name}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> updateField('name', e.target.value)}
        placeholder="Your name"
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{formData.email}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> updateField('email', e.target.value)}
        placeholder="Email address"
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{formData.message}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> updateField('message', e.target.value)}
        placeholder="Your message"
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>
          <span class="hljs-attr">checked</span>=<span class="hljs-string">{formData.subscribe}</span>
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> updateField('subscribe', e.target.checked)}
        /&gt;
        Subscribe to newsletter
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Send Message<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<p>This form demonstrates multiple lazy initialization benefits: error handling, validation, and default fallback values. Users never lose their draft, even after accidental navigation.</p>
<hr />
<h2 id="heading-when-to-use-lazy-initialization">When to Use Lazy Initialization</h2>
<ul>
<li><p><strong>Reading from Browser APIs</strong>: localStorage, sessionStorage, IndexedDB access involves I/O operations.</p>
</li>
<li><p><strong>Complex Calculations</strong>: Mathematical operations, data transformations, or filtering large datasets.</p>
</li>
<li><p><strong>Expensive Object Creation</strong>: Building complex nested structures or instantiating classes.</p>
</li>
<li><p><strong>Reading URL Parameters</strong>: Parsing <a target="_blank" href="http://window.location.search">window.location.search</a> or constructing URLSearchParams objects.</p>
</li>
</ul>
<h2 id="heading-when-not-to-use-lazy-initialization">When NOT to Use Lazy Initialization</h2>
<p><strong>Simple Values</strong>: Don't wrap primitives in functions:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Unnecessary</span>
<span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-function">() =&gt;</span> <span class="hljs-number">0</span>);

<span class="hljs-comment">// Better</span>
<span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
</code></pre>
<p><strong>Props as Initial State</strong>: If the value comes from props and is already computed:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Unnecessary</span>
<span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-function">() =&gt;</span> props.initialValue);

<span class="hljs-comment">// Better</span>
<span class="hljs-keyword">const</span> [value, setValue] = useState(props.initialValue);
</code></pre>
<hr />
<h2 id="heading-performance-comparison">Performance Comparison</h2>
<pre><code class="lang-javascript"><span class="hljs-comment">// Without lazy initialization</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SlowComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> expensiveValue = computeExpensiveValue(); <span class="hljs-comment">// Runs every render</span>
  <span class="hljs-keyword">const</span> [data, setData] = useState(expensiveValue);

  <span class="hljs-keyword">const</span> [counter, setCounter] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-comment">// Every click triggers expensive computation</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCounter(counter + 1)}&gt;Clicks: {counter}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}

<span class="hljs-comment">// With lazy initialization</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">FastComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-function">() =&gt;</span> computeExpensiveValue()); <span class="hljs-comment">// Runs once</span>
  <span class="hljs-keyword">const</span> [counter, setCounter] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-comment">// Clicks no longer trigger expensive computation</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCounter(counter + 1)}&gt;Clicks: {counter}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>In the slow version, every button click re-renders the component and re-computes the expensive value, even though it's never used again. The fast version (functional way) computes it once and skips it on all future renders.</p>
<hr />
<h2 id="heading-common-mistakes">Common Mistakes</h2>
<h3 id="heading-returning-undefined">Returning Undefined</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Wrong: function doesn't return anything</span>
<span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'data'</span>);
});

<span class="hljs-comment">// Correct: explicit return</span>
<span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'data'</span>);
});
</code></pre>
<h3 id="heading-using-function-results-instead-of-functions">Using Function Results Instead of Functions</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Wrong: calls the function immediately</span>
<span class="hljs-keyword">const</span> [data, setData] = useState(computeValue());

<span class="hljs-comment">// Correct: passes the function itself</span>
<span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-function">() =&gt;</span> computeValue());
</code></pre>
<p>The difference is subtle but critical. The first example calls <code>computeValue()</code> on every render. The second passes a function that React calls only once.</p>
<hr />
<h2 id="heading-debugging-lazy-initialization">Debugging Lazy Initialization</h2>
<p>Add logging to verify initialization runs only once:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Initializing state - should see this once'</span>);
  <span class="hljs-keyword">return</span> expensiveComputation();
});
</code></pre>
<p>In React StrictMode (development), you'll see the log twice due to double-rendering, but in production, it executes exactly once.</p>
<hr />
<h2 id="heading-integration-with-typescript">Integration with TypeScript</h2>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> UserPreferences {
  theme: <span class="hljs-string">'light'</span> | <span class="hljs-string">'dark'</span>;
  language: <span class="hljs-built_in">string</span>;
  notifications: <span class="hljs-built_in">boolean</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Settings</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [prefs, setPrefs] = useState&lt;UserPreferences&gt;(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> saved = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'preferences'</span>);
    <span class="hljs-keyword">if</span> (saved) {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.parse(saved) <span class="hljs-keyword">as</span> UserPreferences;
    }
    <span class="hljs-keyword">return</span> {
      theme: <span class="hljs-string">'light'</span>,
      language: <span class="hljs-string">'en'</span>,
      notifications: <span class="hljs-literal">true</span>
    };
  });

  <span class="hljs-keyword">return</span> &lt;div&gt;Current theme: {prefs.theme}&lt;/div&gt;;
}
</code></pre>
<p>TypeScript inference works seamlessly with lazy initialization, providing type safety for your initial state function.</p>
<hr />
<h2 id="heading-notes-key-points">Notes (Key points)</h2>
<p>Lazy initialization optimizes performance by deferring expensive computations until absolutely necessary and ensuring they execute only once. Wrap initialization logic in a function when reading from browser APIs, processing data, or performing calculations.</p>
<p>Skip lazy initialization for simple values and computed props. The function wrapper adds unnecessary overhead for trivial initializations.</p>
<p>Master this pattern to build responsive React applications that feel instant, even when working with complex data structures and expensive operations.</p>
]]></content:encoded></item><item><title><![CDATA[useState Hook in React [part-1]]]></title><description><![CDATA[State management sits at the heart of React development. The useState hook transforms static components into dynamic, interactive experiences. This guide explores building counters with useState, revealing patterns that extend far beyond simple incre...]]></description><link>https://yashrajxdev.blog/usestate-hook-in-react-part-1</link><guid isPermaLink="true">https://yashrajxdev.blog/usestate-hook-in-react-part-1</guid><category><![CDATA[React]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[CSS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Java]]></category><category><![CDATA[software development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Angular]]></category><category><![CDATA[React Native]]></category><category><![CDATA[Rust]]></category><category><![CDATA[AI]]></category><category><![CDATA[cursor]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Wed, 31 Dec 2025 20:03:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136129552/8abe2f09-3d14-4703-af56-aa40d563da15.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>State management sits at the heart of React development. The <code>useState</code> hook transforms static components into dynamic, interactive experiences. This guide explores building counters with useState, revealing patterns that extend far beyond simple increment buttons.</p>
<h2 id="heading-understanding-usestate-fundamentals">Understanding useState Fundamentals</h2>
<p>The useState hook enables functional components to maintain and <mark>update local state</mark>. <strong>It returns an array containing the current state value and a function to update it.</strong></p>
<p>It must be defined and used inside functional component only.</p>
<p><code>useState</code> is a fundamental React Hook that lets functional components manage state (data that changes over time) by declaring a state variable, its initial value, and a function to update it, returning them as an array <code>[stateValue, setStateFunction]</code>. It's <strong><mark>used for simple state like numbers, strings, objects, or arrays</mark></strong>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
</code></pre>
<p>Here count is a variable, it’s value can be updated only using setCount function.</p>
<p>This elegant API masks sophisticated behavior. React tracks state changes, <strong><em>triggers re-renders</em></strong>, and ensures your UI stays synchronized with application data.</p>
<p><strong>How it works</strong></p>
<ul>
<li><p><strong>Import:</strong> <code>import { useState } from 'react';</code>.</p>
</li>
<li><p><strong>Declaration:</strong> <code>const [count, setCount] = useState(0);</code>.</p>
<ul>
<li><p><code>count</code>: The current state value (e.g., <code>0</code>).</p>
</li>
<li><p><code>setCount</code>: The function to update <code>count</code>.</p>
</li>
<li><p><code>useState(0)</code>: Sets the initial value (can be any data type).</p>
</li>
</ul>
</li>
<li><p><strong>Updating:</strong> Call the setter function, e.g., <code>setCount(count + 1)</code> or <code>setCount(prevCount =&gt; prevCount + 1)</code>. Difference b/w this is when you want to update previous value, when there is count getting updated more than one time. First one will only update once even though called multiple times.</p>
</li>
<li><p><strong>Re-render:</strong> Calling the setter function tells React to re-render the component with the new state value. </p>
</li>
</ul>
<p>A regular variable is like a <strong>whiteboard</strong> that gets erased every time you leave the room (re-render). <code>useState</code> is like a <strong>notebook</strong> where React writes down the value so it is waiting for you when you come back.</p>
<p><strong><mark>IMP</mark></strong> Internally, React holds state in an array or a similar structure associated with that specific component's position in the UI tree. When it is re-render react checks the stored value if it is updated then react ignores the initial state. The state remains stored as long as the component remains in its specific position in the UI tree (it is "mounted").</p>
<p><strong><mark>IMP</mark></strong> One important point is that when a state requires complex computation for its initial value, it should be initialized using a function, for example: <code>useState(() =&gt; getInitialValue())</code>. If the state is initialized directly, the computation may run on every re-render. However, when using the functional initializer, the function is executed only on the first render, which improves performance.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Correct: The function is only called once</span>
<span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-function">() =&gt;</span> performExpensiveTask());

<span class="hljs-comment">// Incorrect: performExpensiveTask() runs on every single render</span>
<span class="hljs-keyword">const</span> [data, setData] = useState(performExpensiveTask());
</code></pre>
<hr />
<h2 id="heading-building-a-counter">Building a Counter</h2>
<p>Let's build a counter that demonstrates real-world patterns you'll use across React applications.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">InteractiveCounter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> increment = <span class="hljs-function">() =&gt;</span> setCount(count + <span class="hljs-number">1</span>);
  <span class="hljs-keyword">const</span> decrement = <span class="hljs-function">() =&gt;</span> setCount(count - <span class="hljs-number">1</span>);
  <span class="hljs-keyword">const</span> reset = <span class="hljs-function">() =&gt;</span> setCount(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"counter-container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Current Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"button-group"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{decrement}</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{count</span> === <span class="hljs-string">0}</span>&gt;</span>
          Decrease
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{reset}</span>&gt;</span>Reset<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{increment}</span>&gt;</span>Increase<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"counter-status"</span>&gt;</span>
        {count === 0 &amp;&amp; "Start counting!"}
        {count &gt; 0 &amp;&amp; `You've counted ${count} times`}
        {count <span class="hljs-tag">&lt; <span class="hljs-attr">0</span> &amp;&amp; "<span class="hljs-attr">Negative</span> <span class="hljs-attr">territory</span>!"}
      &lt;/<span class="hljs-attr">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Every call to <code>setCount</code> schedules a re-render. React compares the new state with the previous state. If they differ, React updates the component and its children.</p>
<h3 id="heading-real-world-counter-applications">Real-World Counter Applications</h3>
<p>Counters appear everywhere in production applications:</p>
<ul>
<li><p><strong>Inventory Management</strong>: Track product quantities with increment/decrement controls.</p>
</li>
<li><p><strong>Shopping Carts</strong>: Adjust item quantities before checkout.</p>
</li>
<li><p><strong>Form Inputs</strong>: Create numeric steppers for age, quantity, or rating inputs.</p>
</li>
<li><p><strong>Analytics Dashboards</strong>: Display real-time counters for metrics like page views or active users.</p>
</li>
</ul>
<h2 id="heading-advanced-counter-multi-step-incrementer">Advanced Counter: Multi-Step Incrementer</h2>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SmartCounter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [step, setStep] = useState(<span class="hljs-number">1</span>);

  <span class="hljs-keyword">const</span> adjustCount = <span class="hljs-function">(<span class="hljs-params">direction</span>) =&gt;</span> {
    setCount(count + (step * direction));
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
          Step Size:
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{step}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setStep(Number(e.target.value))}
            min="1"
          /&gt;
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> adjustCount(-1)}&gt;-{step}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> adjustCount(1)}&gt;+{step}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>This example combines multiple state values and demonstrates controlled inputs, a critical pattern for form handling.</p>
<hr />
<h3 id="heading-common-pitfalls-to-avoid">Common Pitfalls to Avoid</h3>
<p><strong>Direct State Mutation</strong></p>
<p><mark>Never modify state directly:</mark></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Wrong</span>
count = count + <span class="hljs-number">1</span>;

<span class="hljs-comment">// Correct</span>
setCount(count + <span class="hljs-number">1</span>);
</code></pre>
<p>Direct mutation bypasses React state management, preventing re-renders and breaking your UI.</p>
<h3 id="heading-performance-considerations">Performance Considerations</h3>
<p>useState updates are efficient for simple values like numbers and strings. For primitive values, this comparison is instantaneous (quick ~ O(1)).</p>
<p>Multiple state updates in the same event handler are batched automatically in React 18+, preventing unnecessary re-renders. In same function all useState update will count to one render only.</p>
<h3 id="heading-testing-state-updates">Testing State Updates</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { render, screen, fireEvent } <span class="hljs-keyword">from</span> <span class="hljs-string">'@testing-library/react'</span>;

test(<span class="hljs-string">'increments counter'</span>, <span class="hljs-function">() =&gt;</span> {
  render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">InteractiveCounter</span> /&gt;</span></span>);
  <span class="hljs-keyword">const</span> button = screen.getByText(<span class="hljs-string">'Increase'</span>);

  fireEvent.click(button);
  expect(screen.getByText(<span class="hljs-regexp">/Current Count: 1/</span>)).toBeInTheDocument();
});
</code></pre>
<p>Testing state changes validates your component's core functionality.</p>
]]></content:encoded></item><item><title><![CDATA[Controlled vs. Uncontrolled Components in React]]></title><description><![CDATA[In React, the terms controlled and uncontrolled primarily describe how form elements (like <input>, <select>, or <textarea>) handle their internal state.
1. Controlled Components
In a controlled component, the form data is handled by the React compon...]]></description><link>https://yashrajxdev.blog/controlled-vs-uncontrolled-components-in-react</link><guid isPermaLink="true">https://yashrajxdev.blog/controlled-vs-uncontrolled-components-in-react</guid><category><![CDATA[React]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[frontend]]></category><category><![CDATA[front-end]]></category><category><![CDATA[System Design]]></category><category><![CDATA[Google]]></category><category><![CDATA[Meta]]></category><category><![CDATA[MERN Stack]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Angular]]></category><dc:creator><![CDATA[Yashraj]]></dc:creator><pubDate>Sat, 27 Dec 2025 17:40:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768136090978/4bb1cfb9-aeba-45fa-a25b-5e35c1129adf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In React, the terms <strong>controlled</strong> and <strong>uncontrolled</strong> primarily describe how form elements (like <code>&lt;input&gt;</code>, <code>&lt;select&gt;</code>, or <code>&lt;textarea&gt;</code>) handle their internal state.</p>
<h2 id="heading-1-controlled-components"><strong>1. Controlled Components</strong></h2>
<p>In a controlled component, the form data is handled by the <strong>React component state</strong>. React is the "single source of truth".</p>
<p>React state controls the input value. Every keystroke updates state.</p>
<p><strong>How it works</strong>: The input's <code>value</code> is bound to a state variable (e.g., via <code>useState</code>). Every time the user types, an <code>onChange</code> handler updates that state, which then re-renders the input with the new value.</p>
<p><strong>Best for</strong>:</p>
<ul>
<li><p><strong>Real-time validation</strong>: Checking if a password is long enough as the user types.</p>
</li>
<li><p><strong>Conditional UI</strong>: Disabling a submit button until all fields are valid.</p>
</li>
<li><p><strong>Format enforcement</strong>: Automatically formatting a phone number or forcing uppercase.</p>
</li>
</ul>
<p><strong>Downside</strong>: Can be verbose (requires more boilerplate code) and may cause performance issues in extremely large forms due to frequent <strong>re-renders</strong> (Since state will update when change in input).</p>
<p><strong>When to use:</strong> When you need instant validation, formatting, or conditional rendering based on input.</p>
<p><strong><mark>Example</mark></strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">LoginForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> [password, setPassword] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();
    <span class="hljs-comment">// Validate before sending</span>
    <span class="hljs-keyword">if</span> (!email.includes(<span class="hljs-string">'@'</span>)) {
      alert(<span class="hljs-string">'Invalid email'</span>);
      <span class="hljs-keyword">return</span>;
    }
    <span class="hljs-built_in">console</span>.log({ email, password });
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{email}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setEmail(e.target.value)}
        placeholder="Email"
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{password}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setPassword(e.target.value)}
        placeholder="Password"
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<hr />
<h2 id="heading-2-uncontrolled-components"><strong>2. Uncontrolled Components</strong></h2>
<p>In an uncontrolled component, the form data is handled by the <strong>DOM itself</strong>. </p>
<p><strong>How it works</strong>: You use a <code>ref</code> (via <code>useRef</code>) / JavaScript methods to "pull" the value from the DOM element only when you need it (e.g., upon form submission). You can set an initial value using the <code>defaultValue</code> prop.</p>
<p><strong>Best for</strong>:</p>
<ul>
<li><strong>Simple forms</strong>: When you only need the value once at the end.</li>
</ul>
<ul>
<li><strong>Non-React integration</strong>: When using third-party libraries that directly manipulate the DOM.</li>
</ul>
<ul>
<li><strong>Large forms</strong>: Where reducing re-renders is critical for performance.</li>
</ul>
<p>One benefit of uncontrolled components is they work seamlessly with browser's built-in features like <code>autoComplete</code>, form validation, and password managers without additional code.</p>
<pre><code class="lang-javascript">&lt;input 
  ref={emailRef}
  name=<span class="hljs-string">"email"</span>
  autoComplete=<span class="hljs-string">"email"</span>
  <span class="hljs-comment">// ↑ Browser handles everything automatically</span>
/&gt;
</code></pre>
<p><strong>Downside</strong>: You lose granular control; you cannot easily react to changes in real-time or enforce complex formatting.</p>
<p><strong>When to use:</strong> File inputs (must be uncontrolled), simple forms, third-party DOM integrations, performance-critical inputs.</p>
<p><strong><mark>Example</mark></strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">FileUpload</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> fileRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> nameRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();
    <span class="hljs-keyword">const</span> file = fileRef.current.files[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">const</span> name = nameRef.current.value;

    <span class="hljs-keyword">if</span> (!file) {
      alert(<span class="hljs-string">'Select a file'</span>);
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> formData = <span class="hljs-keyword">new</span> FormData();
    formData.append(<span class="hljs-string">'file'</span>, file);
    formData.append(<span class="hljs-string">'name'</span>, name);

    <span class="hljs-comment">// Send to API</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Uploading:'</span>, { name, <span class="hljs-attr">file</span>: file.name });
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">ref</span>=<span class="hljs-string">{nameRef}</span>
        <span class="hljs-attr">defaultValue</span>=<span class="hljs-string">"Untitled"</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"File name"</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">ref</span>=<span class="hljs-string">{fileRef}</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span>
        <span class="hljs-attr">accept</span>=<span class="hljs-string">"image/*"</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Upload<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<hr />
<h3 id="heading-quick-decision-guide">Quick Decision Guide</h3>
<ul>
<li><p><strong>Need live validation/formatting?</strong> → Controlled</p>
</li>
<li><p><strong>Just need the value on submit?</strong> → Uncontrolled</p>
</li>
<li><p><strong>File input?</strong> → Must be uncontrolled</p>
</li>
<li><p><strong>Thousands of inputs?</strong> → Consider uncontrolled for performance</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>