<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrii Vyhovanok</title>
    <description>The latest articles on DEV Community by Andrii Vyhovanok (@andrii_vyhovanok_6148f3b3).</description>
    <link>https://dev.to/andrii_vyhovanok_6148f3b3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2899086%2F5735a884-dde8-4917-8086-d141ebad80e2.png</url>
      <title>DEV Community: Andrii Vyhovanok</title>
      <link>https://dev.to/andrii_vyhovanok_6148f3b3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrii_vyhovanok_6148f3b3"/>
    <language>en</language>
    <item>
      <title>A deep dive into React Hooks (useState, useEffect)</title>
      <dc:creator>Andrii Vyhovanok</dc:creator>
      <pubDate>Wed, 26 Feb 2025 11:13:14 +0000</pubDate>
      <link>https://dev.to/andrii_vyhovanok_6148f3b3/a-deep-dive-into-react-hooks-usestate-useeffect-2pan</link>
      <guid>https://dev.to/andrii_vyhovanok_6148f3b3/a-deep-dive-into-react-hooks-usestate-useeffect-2pan</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction✋😃&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Greetings, everyone! Today, we will explore how basic hooks work in React.&lt;br&gt;
 To fully understand their logic, it is essential to have a basic understanding of React's internal mechanism - &lt;strong&gt;Fiber&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What is Fiber?🧠&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fiber&lt;/strong&gt; is an object that represents a node in the virtual DOM and serves as the foundation of modern React. It allows React to perform &lt;strong&gt;flexible, asynchronous, interruptible, and prioritized rendering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each component, for example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;ComponentButton /&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is a separate Fiber node, which contains information about state, props, and links to other components.&lt;br&gt;
The main role of Fiber is to efficiently manage updates and rendering priorities.&lt;br&gt;
&lt;em&gt;(&lt;strong&gt;Fiber&lt;/strong&gt; is created during React initialization via &lt;strong&gt;ReactDOM.createRoot()&lt;/strong&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What is useState📄&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;According to &lt;a href="https://react.dev/reference/react/useState" rel="noopener noreferrer"&gt;React documentation&lt;/a&gt;, useState is a React Hook that lets you add a state variable to your component.&lt;/p&gt;
&lt;h2&gt;
  
  
  How does useState work under the hood?⚙️
&lt;/h2&gt;

&lt;p&gt;Let's examine the basic state initialization:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [status, setStatus] = useState("useState under the hood: On Mount");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Internally, React executes the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useState: function (initialState) {
   initialState = mountStateImpl(initialState);
   var queue = initialState.queue,
   dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
   queue.dispatch = dispatch;
   return [initialState.memoizedState, dispatch];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Summary💡:&lt;/strong&gt;&lt;br&gt;
This code initializes &lt;strong&gt;useState&lt;/strong&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storing the initial value in &lt;strong&gt;memoizedState&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Creating a &lt;strong&gt;queue&lt;/strong&gt; for future updates.&lt;/li&gt;
&lt;li&gt;Returning &lt;strong&gt;[&lt;em&gt;the given value, a function to update it&lt;/em&gt;]&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Detailed breakdown🔎:&lt;/strong&gt;&lt;br&gt;
In the &lt;strong&gt;mountStateImpl&lt;/strong&gt; function, we use &lt;strong&gt;mountWorkInProgressHook&lt;/strong&gt;, which checks whether this is the first hook in the component.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If it is the first hook, it is stored in &lt;strong&gt;memoizedState&lt;/strong&gt;, which is part of Fiber.&lt;/li&gt;
&lt;li&gt;If there was another hook before it, &lt;strong&gt;memoizedState&lt;/strong&gt; will contain a special &lt;strong&gt;next&lt;/strong&gt; field that links the new hook to the previous one.&lt;/li&gt;
&lt;li&gt;This process continues &lt;em&gt;until all hooks are added&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How does &lt;strong&gt;memoizedState&lt;/strong&gt; look after &lt;strong&gt;initialization&lt;/strong&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "memoizedState": "useState under the hood: On Mount",
  "baseState": "useState under the hood: On Mount",
  "baseQueue": null,
  "queue": {
    "pending": null,
    "lanes": 0,
    "dispatch": null,
    "lastRenderedState": "useState under the hood: On Mount"
  },
  "next": null
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to create a &lt;strong&gt;queue&lt;/strong&gt; to store future updates, but the hook is not added to the queue until the setState call (setStatus in our example)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Determining whether useState receives a primitive or a function:&lt;/strong&gt;&lt;br&gt;
React checks whether the value passed to &lt;strong&gt;useState&lt;/strong&gt; is a primitive or a function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (typeof initialState === "function") {    
    var initialStateInitializer = initialState;
    initialState = initialStateInitializer();
}
hook.memoizedState = hook.baseState = initialState;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If a &lt;strong&gt;primitive value&lt;/strong&gt; is passed (e.g., 10 or "hello"), it is simply stored in &lt;strong&gt;memoizedState&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If a &lt;strong&gt;function&lt;/strong&gt; is passed, it is executed, and its result is stored in &lt;strong&gt;memoizedState&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Creating the dispatch function 🚀&lt;/strong&gt;&lt;br&gt;
Once the hook's value is determined, React creates a function that will update this value.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;dispatch&lt;/strong&gt; method, which is returned from &lt;strong&gt;useState&lt;/strong&gt; as the second element of the array.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;dispatch&lt;/strong&gt; function is created inside &lt;strong&gt;dispatchSetState&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function dispatchSetState(fiber, queue, action) {
  var lane = requestUpdateLane();
  dispatchSetStateInternal(fiber, queue, action, lane);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;dispatchSetState&lt;/strong&gt; function determines the update priority (&lt;strong&gt;lane&lt;/strong&gt;) in Fiber and calls the &lt;strong&gt;dispatchSetStateInternal&lt;/strong&gt; method (this method is quite large so we won't show it here).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dispatchSetStateInternal&lt;/strong&gt; performs several important checks, including whether rendering is currently in progress to prevent an infinite loop of updates.&lt;/p&gt;

&lt;p&gt;If a re-render is not occurring at that moment, React checks whether the new value differs from the previous one.&lt;/p&gt;

&lt;p&gt;This optimization is crucial because if the value is identical, the re-render does not happen - React simply adds this update to the queue (&lt;strong&gt;updateQueue&lt;/strong&gt;) to maintain the correct execution order of hooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is the new value calculated?🧮&lt;/strong&gt;&lt;br&gt;
React determines whether we have passed a primitive value or a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function basicStateReducer(state, action) {
  return typeof action === "function" ? action(state) : action;
}

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

&lt;/div&gt;



&lt;p&gt;How does this look in practice?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// primitive value
setStatus("useState under the hood: On Update");
// function 
setStatus((status) =&amp;gt; `${status} - On Update`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the first case, a primitive value is passed and stored in &lt;strong&gt;memoizedState&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the second case, a function is passed, which receives the previous value and returns the updated one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the new value differs from the previous one, React updates the state object, adds the update to the queue (&lt;strong&gt;updateQueue&lt;/strong&gt;), and triggers a re-render.&lt;/p&gt;

&lt;p&gt;Until the re-render occurs, React accumulates all changes in the queue so that they can be executed in one pass while maintaining the correct execution order of hooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Re-rendering phase (renderWithHooks)🔄&lt;/strong&gt;&lt;br&gt;
At the re-rendering stage (&lt;strong&gt;renderWithHooks&lt;/strong&gt;), React checks whether the state value already exists.&lt;/p&gt;

&lt;p&gt;When the following line of code is executed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [status, setStatus] = useState("useState under the hood: On Mount");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;React determines whether to use the existing value from &lt;strong&gt;memoizedState&lt;/strong&gt; (updated) or initialize &lt;strong&gt;useState&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does React determine whether to initialize the hook?&lt;/strong&gt;&lt;br&gt;
This happens inside &lt;strong&gt;renderWithHooks&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function renderWithHooks(
  current,
  workInProgress,
  Component,
  props,
  secondArg,
  nextRenderLanes
) {
  ReactSharedInternals.H =
    null === current || null === current.memoizedState
      ? HooksDispatcherOnMount
      : HooksDispatcherOnUpdate;
  finishRenderingHooks(current);
  return nextRenderLanes;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;strong&gt;current&lt;/strong&gt; or &lt;strong&gt;current.memoizedState&lt;/strong&gt; is &lt;strong&gt;null&lt;/strong&gt;, React uses &lt;strong&gt;HooksDispatcherOnMount&lt;/strong&gt; to initialize hooks.&lt;/li&gt;
&lt;li&gt;If &lt;strong&gt;memoizedState&lt;/strong&gt; already exists, React uses &lt;strong&gt;HooksDispatcherOnUpdate&lt;/strong&gt;, which works with the current state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, if &lt;strong&gt;memoizedState&lt;/strong&gt; exists, &lt;strong&gt;useState&lt;/strong&gt; calls &lt;strong&gt;updateReducer&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useState: function () {
  return updateReducer(basicStateReducer);
}
function basicStateReducer(state, action) {
  return typeof action === "function" ? action(state) : action;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does this mean?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;useState&lt;/strong&gt; uses &lt;strong&gt;updateReducer&lt;/strong&gt;, where &lt;strong&gt;basicStateReducer&lt;/strong&gt; updates the state.&lt;/li&gt;
&lt;li&gt;This means that &lt;strong&gt;useState&lt;/strong&gt; and &lt;strong&gt;useReducer&lt;/strong&gt; operate on the same mechanism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useState&lt;/strong&gt; is a more convenient version of &lt;strong&gt;useReducer&lt;/strong&gt; with a fixed reducer, &lt;strong&gt;basicStateReducer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How is the state updated?&lt;/strong&gt;&lt;br&gt;
In &lt;strong&gt;updateReducer&lt;/strong&gt;, &lt;strong&gt;memoizedState&lt;/strong&gt; is updated, and after a re-render, we get a new value ready for use.&lt;/p&gt;
&lt;h2&gt;
  
  
  Analogy: Auto-save in a Video Game 🎮
&lt;/h2&gt;

&lt;p&gt;As an analogy, we can imagine a computer game with an auto-save feature.&lt;br&gt;
The game environment is our &lt;strong&gt;Fiber&lt;/strong&gt;, which contains information about all the characters, their attributes, items, and enemies.&lt;br&gt;
The entire game state can change, but the game will run slowly if we perform an auto-save after every single change.&lt;br&gt;
Therefore, all changes (such as enemies losing health) are first added to a change queue (similar to &lt;strong&gt;updateQueue&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Auto-save (rendering) does not occur immediately after every action but waits for the right moment.&lt;br&gt;
For example, when a player picks up a rare artifact that affects their health or experience.&lt;/p&gt;

&lt;p&gt;This is similar to how &lt;strong&gt;setState&lt;/strong&gt; works:&lt;br&gt;
We can call &lt;strong&gt;setState&lt;/strong&gt;, but React does not update all components immediately - instead, it accumulates changes and applies them at the most optimal moment.&lt;/p&gt;

&lt;p&gt;This allows the game to run smoothly and React to efficiently update the UI!&lt;/p&gt;
&lt;h2&gt;
  
  
  Scheme of useState
&lt;/h2&gt;

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

&lt;p&gt;According to &lt;a href="https://react.dev/reference/react/useEffect" rel="noopener noreferrer"&gt;React documentation&lt;/a&gt;, &lt;strong&gt;useEffect&lt;/strong&gt; is a React Hook that lets you synchronize a component with an external system.&lt;br&gt;
&lt;strong&gt;useEffect&lt;/strong&gt; allowing us to perform side effects in functional components.&lt;br&gt;
With it, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute code after the initial render.&lt;/li&gt;
&lt;li&gt;React to state or prop changes.&lt;/li&gt;
&lt;li&gt;Perform cleanup before the component is unmounted&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How does useEffect work under the hood?🌀
&lt;/h2&gt;

&lt;p&gt;React processes &lt;strong&gt;useEffect&lt;/strong&gt; in three main stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initialization&lt;/strong&gt; (mountEffectImpl)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update&lt;/strong&gt; (updateEffectImpl)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution&lt;/strong&gt; (commitHookEffectListMount)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Initialization of useEffect and Setting Flags🚩&lt;/strong&gt;&lt;br&gt;
When a component is rendered for the first time, React registers the effect using &lt;strong&gt;mountEffectImpl&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect: function (create, deps) {
  const PassiveEffect = 8390656;
  const HookHasEffect = 8;
  return mountEffectImpl(PassiveEffect, HookHasEffect, create, deps); 
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What do we have here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;create&lt;/strong&gt; - The function passed to &lt;strong&gt;useEffect&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;deps&lt;/strong&gt; - The dependency array (&lt;strong&gt;null&lt;/strong&gt;, &lt;strong&gt;[]&lt;/strong&gt;, or &lt;strong&gt;[arg1, …argN]&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PassiveEffect&lt;/strong&gt; - Indicates that &lt;strong&gt;useEffect&lt;/strong&gt; runs after the DOM update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HookHasEffect&lt;/strong&gt; - Signals that the effect should be executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React stores this effect in Fiber as an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "memoizedState": {
    "create": function () { ... }, // Effect code
    "deps": [count], // Dependency array
    "destroy": null, // Cleanup function
    "next": null // Reference to the next effect
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How Dependencies Work&lt;/strong&gt;&lt;br&gt;
If &lt;strong&gt;deps === null&lt;/strong&gt;, the effect runs after every re-render.&lt;br&gt;
If &lt;strong&gt;deps === []&lt;/strong&gt;, the effect runs only once after the initial render.&lt;br&gt;
If &lt;strong&gt;deps === [count]&lt;/strong&gt;, the effect runs whenever count changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update (updateEffectImpl)🚀&lt;/strong&gt;&lt;br&gt;
When the component updates, React checks whether the effect needs to be re-run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Code in updateEffectImpl:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
  var hook = updateWorkInProgressHook();
  deps = deps === undefined ? null : deps;
  var inst = hook.memoizedState.inst;

  if (
    currentHook !== null &amp;amp;&amp;amp;
    deps !== null &amp;amp;&amp;amp;
    areHookInputsEqual(deps, currentHook.memoizedState.deps)
  ) {
    // ❌ `deps` did not change → effect WILL NOT run!
    hook.memoizedState = pushEffect(hookFlags, create, inst, deps);
  } else {
    // ✅ `deps` changed → effect will run after DOM update!
    currentlyRenderingFiber$1.flags |= fiberFlags;
    hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens here?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React retrieves the &lt;strong&gt;previous dependencies&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It performs a check:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;areHookInputsEqual(deps, currentHook.memoizedState.deps)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3.1. If &lt;strong&gt;deps&lt;/strong&gt; did not change, the effect is added to Fiber without updating &lt;strong&gt;fiberFlags&lt;/strong&gt; (if flags are NOT updated, the effect WILL NOT run).&lt;br&gt;
3.2. If &lt;strong&gt;deps&lt;/strong&gt; changed, &lt;strong&gt;fiberFlags&lt;/strong&gt; are updated, signaling React to execute the effect in the commit phase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The internal structure of areHookInputsEqual&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function areHookInputsEqual(nextDeps, prevDeps) {
  if (prevDeps === null || nextDeps === null) {
    return false;
  }

  for (let i = 0; i &amp;lt; prevDeps.length &amp;amp;&amp;amp; i &amp;lt; nextDeps.length; i++) {
    if (!Object.is(nextDeps[i], prevDeps[i])) {
      return false;
    }
  }
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Object.is() compares each dependency, and if at least one &lt;strong&gt;changed&lt;/strong&gt;, React marks the effect for execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executing useEffect (commitHookEffectListMount)
&lt;/h2&gt;

&lt;p&gt;After the DOM update, React runs all effects that have the appropriate &lt;strong&gt;flags&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function commitHookEffectListMount(flags, finishedWork) {
  const updateQueue = finishedWork.updateQueue;
  if (updateQueue !== null) {
    const lastEffect = updateQueue.lastEffect;
    if (lastEffect !== null) {
      let effect = lastEffect.next;
      do {
        if ((effect.tag &amp;amp; flags) === flags) { // Checking `flags`
          var create = effect.create,
              inst = effect.inst;
          var cleanup = create(); // Running `useEffect`
          inst.destroy = cleanup; // Storing cleanup function
        }
        effect = effect.next;
      } while (effect !== lastEffect.next);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How It Works:&lt;/strong&gt;&lt;br&gt;
React checks the &lt;strong&gt;flags&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if ((effect.tag &amp;amp; flags) === flags)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;strong&gt;flags&lt;/strong&gt; contain &lt;strong&gt;PassiveEffect&lt;/strong&gt;, the effect is executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.1. Calls &lt;strong&gt;effect.create()&lt;/strong&gt; (user-defined function inside &lt;strong&gt;useEffect&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;1.2. If &lt;strong&gt;useEffect&lt;/strong&gt; returns a cleanup function, it is stored in &lt;strong&gt;inst.destroy&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If flags are not set, the effect is skipped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step-by-Step Example of useEffect&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const [count, setCount] = useState(0);

  useEffect(() =&amp;gt; {
    console.log("useEffect executed!");
    return () =&amp;gt; console.log("Cleanup effect!");
  }, [count]);

return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; {
        setCount(() =&amp;gt; { 
          if (count &amp;gt; 1) return count; 
          return count + 1; 
          })
        }}&amp;gt;
        Increment
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Execution Flow&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;First Render (count = 0)&lt;/strong&gt;&lt;br&gt;
deps = [0], prevDeps = null → &lt;strong&gt;Effect runs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clicking the Button (count = 1)&lt;/strong&gt;&lt;br&gt;
deps = [1], prevDeps = [0] → &lt;strong&gt;Effect runs again&lt;/strong&gt;.&lt;br&gt;
Before executing the new effect, &lt;strong&gt;cleanup()&lt;/strong&gt; is called.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clicking the Button Again (count = 1 again)&lt;/strong&gt;&lt;br&gt;
deps = [1], prevDeps = [1] → &lt;strong&gt;Effect does not run&lt;/strong&gt;.&lt;br&gt;
areHookInputsEqual([1], [1]) === true&lt;/p&gt;

&lt;h2&gt;
  
  
  Analogy: Event Manager in a Video Game 🎮
&lt;/h2&gt;

&lt;p&gt;Imagine our computer game has an &lt;strong&gt;event manager&lt;/strong&gt; responsible for triggering various game mechanics.&lt;/p&gt;

&lt;p&gt;However, this manager doesn't just execute all events at once - it follows specific rules to optimize performance and efficiency:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observing Changes (deps)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The event manager constantly monitors external factors, such as the time of day or the collection of an important item.&lt;br&gt;
For example, if night turns into day, this may trigger a new event - new characters appearing or environmental changes.&lt;br&gt;
In React, this is similar to &lt;strong&gt;deps&lt;/strong&gt; - if dependencies change, &lt;strong&gt;useEffect&lt;/strong&gt; will execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cleaning Up Before Executing a New Event (cleanup())&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before starting a new quest, the game automatically saves progress (auto-save).&lt;br&gt;
Similarly, before switching to nighttime music, the game stops playing the daytime soundtrack.&lt;br&gt;
 This is analogous to &lt;strong&gt;cleanup()&lt;/strong&gt; in &lt;strong&gt;useEffect&lt;/strong&gt;, which runs before a new effect is executed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executing the Event (useEffect triggers)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the event manager detects that external conditions have changed, it triggers a new effect.&lt;br&gt;
For example, when night falls, the manager spawns monsters, changes the soundtrack, and activates night mechanics.&lt;br&gt;
This is how &lt;strong&gt;useEffect&lt;/strong&gt; works - it executes when dependencies change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Event Manager Keeps Running Until the Game Closes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before exiting the game, the manager may perform final cleanup actions (like one last auto-save).&lt;br&gt;
For instance, the game saves the progress again, so that the player returns to the same point next time.&lt;br&gt;
This is similar to the final cleanup() that runs before a component is unmounted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Congratulations
&lt;/h2&gt;

&lt;p&gt;Congratulations! We've explored two of the most essential and widely used hooks in React - useState and useEffect - in great detail. I hope this deep dive helps you gain a better understanding of how hooks work under the hood and how to use them effectively in your projects.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
