<?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: Gautam</title>
    <description>The latest articles on DEV Community by Gautam (@gautam_f015817a44372df414).</description>
    <link>https://dev.to/gautam_f015817a44372df414</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4026028%2Fa51e5d1f-b110-4591-89c8-9808cf781251.jpg</url>
      <title>DEV Community: Gautam</title>
      <link>https://dev.to/gautam_f015817a44372df414</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gautam_f015817a44372df414"/>
    <language>en</language>
    <item>
      <title>10 React Hooks Interview Questions That Actually Trip People Up (With Explanations)</title>
      <dc:creator>Gautam</dc:creator>
      <pubDate>Sun, 12 Jul 2026 12:42:05 +0000</pubDate>
      <link>https://dev.to/gautam_f015817a44372df414/10-react-hooks-interview-questions-that-actually-trip-people-up-with-explanations-2d3g</link>
      <guid>https://dev.to/gautam_f015817a44372df414/10-react-hooks-interview-questions-that-actually-trip-people-up-with-explanations-2d3g</guid>
      <description>&lt;p&gt;If you've been prepping for &lt;strong&gt;React interviews&lt;/strong&gt;, you've probably noticed most &lt;em&gt;interview question&lt;/em&gt; lists online are either too basic (what is useState) or copy-pasted from the same five articles. So I put together a list of &lt;strong&gt;hooks questions&lt;/strong&gt; that come up often in real interviews — the kind that sound simple but expose whether you actually understand what's happening under the hood.&lt;/p&gt;

&lt;p&gt;Let's go through them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does this useEffect cause an infinite loop?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer: No &lt;strong&gt;dependency array&lt;/strong&gt; means the effect runs after every render.&lt;br&gt;
Since it updates state on every run, it triggers another render, which&lt;br&gt;
triggers the effect again — forever. Add &lt;strong&gt;[]&lt;/strong&gt; if you want it to run once, or a proper dependency array if it should run on specific value changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the difference between useMemo and useCallback?
&lt;/h2&gt;

&lt;p&gt;Both cache something between renders, but:&lt;/p&gt;

&lt;p&gt;**useMemo **caches a value (the result of a computation)&lt;br&gt;
**useCallback **caches a function reference&lt;/p&gt;

&lt;p&gt;A common gotcha: useCallback(fn, deps) is literally equivalent to&lt;br&gt;
useMemo(() =&amp;gt; fn, deps). If you understand that, you understand both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does my state update not reflect immediately after setState?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aman&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// still logs "Aman"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer: State updates are **asynchronous **and batched. name inside&lt;br&gt;
handleClick is a snapshot from the current render's closure — it won't&lt;br&gt;
reflect the update until the component re-renders.&lt;/p&gt;

&lt;h2&gt;
  
  
  What problem does **useRef **solve that **useState **can't?
&lt;/h2&gt;

&lt;p&gt;useRef gives you a mutable object that persists across renders without&lt;br&gt;
triggering a re-render when it changes. Great for:&lt;/p&gt;

&lt;p&gt;Storing a DOM node reference&lt;br&gt;
Keeping a mutable value (like a timer ID) that shouldn't cause a re-render&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do &lt;strong&gt;custom hooks&lt;/strong&gt; need to start with "use"?
&lt;/h2&gt;

&lt;p&gt;It's not just convention — it's how React's linter (and React itself) knows to apply the Rules of Hooks (no conditional calls, no calls inside loops) to your custom hook. Name it getSomething instead of useSomething and &lt;strong&gt;ESLint's&lt;/strong&gt; hooks plugin won't catch violations inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's a stale closure, and how does it happen with hooks?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// always logs the initial value&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer: The effect's closure captures count from the render it was&lt;br&gt;
created in. With an empty dependency array, that closure never updates —&lt;br&gt;
so count is frozen at its initial value forever inside the interval.&lt;/p&gt;

&lt;h2&gt;
  
  
  When would you use &lt;strong&gt;useLayoutEffect **instead of **useEffect&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;Answer: useLayoutEffect runs synchronously before the browser paints. Use it when you need to measure or mutate the DOM before the user sees anything (e.g., preventing a visual flicker when adjusting an element's position). useEffect runs after paint, which is fine for most side effects (data fetching, subscriptions).&lt;/p&gt;

&lt;h2&gt;
  
  
  Can you conditionally call a hook?
&lt;/h2&gt;

&lt;p&gt;No — and interviewers love asking why, not just that. React tracks hooks&lt;br&gt;
by call order per render, not by name. If a hook is skipped in one render&lt;br&gt;
and called in another, the entire hook-state mapping shifts, causing bugs&lt;br&gt;
that are hard to trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the dependency array in &lt;strong&gt;useEffect&lt;/strong&gt; actually compare?
&lt;/h2&gt;

&lt;p&gt;Shallow equality (Object.is), not deep equality. This is why passing an&lt;br&gt;
object or array literal as a dependency causes the effect to run on every&lt;br&gt;
render — a new reference is created every time, even if the contents are&lt;br&gt;
identical.&lt;/p&gt;

&lt;h2&gt;
  
  
  How would you **debounce **a search input using hooks?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useDebounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;debounced&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDebounced&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setDebounced&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;debounced&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;cleanup function&lt;/strong&gt; is the key part — it cancels the previous timer&lt;br&gt;
whenever value changes before the delay finishes, so only the last&lt;br&gt;
keystroke actually triggers the debounced update.&lt;/p&gt;

&lt;p&gt;If you want to test yourself on questions like these interactively (with&lt;br&gt;
instant feedback instead of just reading answers), I've been building&lt;br&gt;
&lt;a href="//www.reactgrind.com"&gt;ReactGrind &lt;/a&gt; — a LeetCode-style platform specifically&lt;br&gt;
for React.js practice. Still actively adding new challenges, so &lt;strong&gt;feedback&lt;/strong&gt; is very welcome if you try it out.&lt;/p&gt;

&lt;p&gt;What's a hooks question that stumped you in an interview? Drop it in the&lt;br&gt;
comments — might turn it into a follow-up post.&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>javascript</category>
      <category>react</category>
    </item>
  </channel>
</rss>
