<?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: dani orooji</title>
    <description>The latest articles on DEV Community by dani orooji (@dani_orooji_d22ad887a00f4).</description>
    <link>https://dev.to/dani_orooji_d22ad887a00f4</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%2F3484871%2F6ad18745-c9a7-4e55-ad9f-3f097b8719b1.jpg</url>
      <title>DEV Community: dani orooji</title>
      <link>https://dev.to/dani_orooji_d22ad887a00f4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dani_orooji_d22ad887a00f4"/>
    <language>en</language>
    <item>
      <title>“When Not to Use useMemo, useCallback, and useReducer in React”</title>
      <dc:creator>dani orooji</dc:creator>
      <pubDate>Sun, 07 Sep 2025 13:18:41 +0000</pubDate>
      <link>https://dev.to/dani_orooji_d22ad887a00f4/when-not-to-use-usememo-usecallback-and-usereducer-in-react-18cc</link>
      <guid>https://dev.to/dani_orooji_d22ad887a00f4/when-not-to-use-usememo-usecallback-and-usereducer-in-react-18cc</guid>
      <description>&lt;p&gt;React gives us some amazing hooks like useCallback, useMemo, and useReducer. They’re powerful, but here’s the catch: using them in the wrong place can actually make your app slower and harder to maintain.&lt;br&gt;
In this post, I’ll break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What each hook does&lt;/li&gt;
&lt;li&gt;When you should use it&lt;/li&gt;
&lt;li&gt;When you shouldn’t use it (common anti-patterns)&lt;/li&gt;
&lt;li&gt;Better real-world examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔹 useCallback&lt;/p&gt;

&lt;p&gt;✅ What it does&lt;br&gt;
Keeps a function reference stable between renders. Useful when passing callbacks to memoized child components.&lt;/p&gt;

&lt;p&gt;❌ When NOT to use it&lt;br&gt;
On simple inline functions (onClick={() =&amp;gt; setOpen(true)})&lt;br&gt;
When you’re not passing the function to a child component&lt;br&gt;
If the child isn’t wrapped in React.memo&lt;br&gt;
✅ Good example&lt;br&gt;
&lt;/p&gt;

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

const Button = memo(({ onClick }) =&amp;gt; {
  console.log("Button rendered");
  return &amp;lt;button onClick={onClick}&amp;gt;Click Me&amp;lt;/button&amp;gt;;
});

export default function App() {
  const [count, setCount] = useState(0);

  // ✅ useCallback prevents function recreation on each render
  const handleClick = useCallback(() =&amp;gt; {
    console.log("Clicked!");
  }, []);

  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(count + 1)}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;Button onClick={handleClick} /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without useCallback, the  would re-render every time count changes.&lt;br&gt;
🔹 useMemo&lt;br&gt;
✅ What it does&lt;br&gt;
Memoizes the result of a calculation so it’s only recomputed when dependencies change.&lt;br&gt;
❌ When NOT to use it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For cheap operations (a + b)&lt;/li&gt;
&lt;li&gt;For small lists or trivial filtering/sorting&lt;/li&gt;
&lt;li&gt;Just “because” (it adds overhead itself)
✅ Good example
&lt;/li&gt;
&lt;/ul&gt;

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

export default function App() {
  const [filter, setFilter] = useState("");
  const [items] = useState(
    Array.from({ length: 10000 }, (_, i) =&amp;gt; `Item ${i + 1}`)
  );

  // ✅ Expensive filtering only runs when "filter" changes
  const filteredItems = useMemo(() =&amp;gt; {
    console.log("Filtering...");
    return items.filter((item) =&amp;gt; item.includes(filter));
  }, [filter, items]);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input
        value={filter}
        onChange={(e) =&amp;gt; setFilter(e.target.value)}
        placeholder="Search..."
      /&amp;gt;
      &amp;lt;ul&amp;gt;
        {filteredItems.slice(0, 10).map((item) =&amp;gt; (
          &amp;lt;li key={item}&amp;gt;{item}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you filter a huge list without useMemo, React would recompute the filter on every keystroke, even if unrelated state changes.&lt;br&gt;
🔹 useReducer&lt;br&gt;
✅ What it does&lt;/p&gt;

&lt;p&gt;Alternative to useState for managing complex state with multiple transitions.&lt;br&gt;
❌ When NOT to use it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When state is simple (isOpen, count, inputValue)&lt;/li&gt;
&lt;li&gt;When you don’t need multiple actions or a reducer function&lt;/li&gt;
&lt;li&gt;For small components where useState is enough
✅ Good example
&lt;/li&gt;
&lt;/ul&gt;

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

function reducer(state, action) {
  switch (action.type) {
    case "add":
      return { ...state, todos: [...state.todos, action.payload] };
    case "remove":
      return {
        ...state,
        todos: state.todos.filter((t, i) =&amp;gt; i !== action.index),
      };
    default:
      return state;
  }
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, { todos: [] });

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "add", payload: "Learn Hooks" })}&amp;gt;
        Add Todo
      &amp;lt;/button&amp;gt;
      &amp;lt;ul&amp;gt;
        {state.todos.map((todo, i) =&amp;gt; (
          &amp;lt;li key={i}&amp;gt;
            {todo}{" "}
            &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "remove", index: i })}&amp;gt;
              ❌
            &amp;lt;/button&amp;gt;
          &amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For complex state transitions like a todo list, shopping cart, or form wizard, useReducer shines. For a simple counter? useState is enough.&lt;br&gt;
💡What about you? Have you ever overused these hooks and then realized they were unnecessary? Share your experience in the comments!&lt;/p&gt;

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