<?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: Gabriel-Ionut Enache</title>
    <description>The latest articles on DEV Community by Gabriel-Ionut Enache (@gabrielenache).</description>
    <link>https://dev.to/gabrielenache</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%2F3772569%2F93fee502-e448-410e-a213-fe5b5e114007.PNG</url>
      <title>DEV Community: Gabriel-Ionut Enache</title>
      <link>https://dev.to/gabrielenache</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrielenache"/>
    <language>en</language>
    <item>
      <title>I Wrote a React Book So You Don't Have to Learn These Lessons the Hard Way</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Sun, 05 Apr 2026 08:43:56 +0000</pubDate>
      <link>https://dev.to/gabrielenache/i-wrote-a-react-book-so-you-dont-have-to-learn-these-lessons-the-hard-way-5b6n</link>
      <guid>https://dev.to/gabrielenache/i-wrote-a-react-book-so-you-dont-have-to-learn-these-lessons-the-hard-way-5b6n</guid>
      <description>&lt;p&gt;A few months ago I attended a React conference and realized something uncomfortable: I'd been writing React for years and I was doing it wrong. Not "broken" wrong — my code worked. But it was slow to maintain, hard to scale, and it wasn't taking advantage of half of what React 19 had to offer.&lt;/p&gt;

&lt;p&gt;That realization turned into a book: &lt;strong&gt;React Best Practices 2026: Scalable Architecture, Design Patterns, Hooks, Performance, and Modern React 19 Techniques&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is this book for?
&lt;/h2&gt;

&lt;p&gt;If you're a mid to senior React developer and you've ever thought "this works, so it's probably fine" — this book is for you. It's not a beginner's guide. It's for developers who already know React and want to write the &lt;em&gt;best&lt;/em&gt; React they possibly can in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually in it?
&lt;/h2&gt;

&lt;p&gt;The book is split into 5 parts covering the full lifecycle of a modern React app:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 1 — Architecture &amp;amp; Patterns&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to design a scalable React architecture from day one&lt;/li&gt;
&lt;li&gt;The composition mindset (and why it changes everything)&lt;/li&gt;
&lt;li&gt;Mastering React without overusing &lt;code&gt;useEffect&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part 2 — Hooks &amp;amp; State&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Context done right — when to use it, when to reach for Zustand&lt;/li&gt;
&lt;li&gt;Writing custom hooks that are actually reusable&lt;/li&gt;
&lt;li&gt;Data consistency with enums and constants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part 3 — Code Quality&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Functional programming in React&lt;/li&gt;
&lt;li&gt;Modern forms with React Hook Form + Zod&lt;/li&gt;
&lt;li&gt;Styling in 2026: Tailwind CSS v4, &lt;code&gt;clsx&lt;/code&gt;, and the &lt;code&gt;cn&lt;/code&gt; utility&lt;/li&gt;
&lt;li&gt;Keeping your JSX clean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part 4 — Performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient rendering with TanStack Virtual&lt;/li&gt;
&lt;li&gt;Stop memoizing everything — let the React Compiler do it&lt;/li&gt;
&lt;li&gt;React Suspense and streaming UIs&lt;/li&gt;
&lt;li&gt;Concurrent UI and optimistic updates&lt;/li&gt;
&lt;li&gt;New React primitives: &lt;code&gt;Activity&lt;/code&gt; and &lt;code&gt;ViewTransition&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part 5 — The Modern Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leveraging AI in your React workflow&lt;/li&gt;
&lt;li&gt;Testing with Vitest and React Testing Library&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A few things I wish I knew earlier
&lt;/h2&gt;

&lt;p&gt;I used &lt;code&gt;useEffect&lt;/code&gt; for everything. Data fetching, derived state, syncing props — all of it. It wasn't until I dug into the docs and started using TanStack Query properly that I understood how much complexity I was creating for myself.&lt;/p&gt;

&lt;p&gt;Same with memoization. I had &lt;code&gt;useMemo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt; scattered everywhere as a performance "just in case". The React Compiler makes most of that unnecessary, and the book walks you through why.&lt;/p&gt;

&lt;p&gt;The chapter on architecture alone could save a team months of painful refactoring down the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  What tools does the book recommend?
&lt;/h2&gt;

&lt;p&gt;The stack covered throughout the book:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;State:&lt;/strong&gt; Zustand for global, Context for auth/theme only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data fetching:&lt;/strong&gt; TanStack Query with &lt;code&gt;useSuspenseQuery&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forms:&lt;/strong&gt; React Hook Form + Zod&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling:&lt;/strong&gt; Tailwind CSS v4 + &lt;code&gt;cn&lt;/code&gt; utility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtualization:&lt;/strong&gt; &lt;code&gt;@tanstack/react-virtual&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing:&lt;/strong&gt; Vitest + Testing Library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build:&lt;/strong&gt; Vite + &lt;code&gt;babel-plugin-react-compiler&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the tools that are winning in 2026. The book shows you how to use them together, not just individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest pitch
&lt;/h2&gt;

&lt;p&gt;I wrote this because attending one conference completely changed how I think about the code I write every day. I want this book to do the same for other developers — without them needing to spend two days in a conference hall in Spain to get there.&lt;/p&gt;

&lt;p&gt;If you're serious about React, this book is worth your time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://gabrielenache.com/react-book-preview" rel="noopener noreferrer"&gt;Get the preview →&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://a.co/d/01h3Dy2l" rel="noopener noreferrer"&gt;Get it on Amazon →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Enache Gabriel-Ionuț is a React developer and the author of React Best Practices 2026.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>I wrote an amazing React Book</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Fri, 13 Mar 2026 18:32:58 +0000</pubDate>
      <link>https://dev.to/gabrielenache/i-wrote-an-amazing-react-book-455g</link>
      <guid>https://dev.to/gabrielenache/i-wrote-an-amazing-react-book-455g</guid>
      <description>&lt;p&gt;In October 2025, I attended the React Alicante conference in Spain. &lt;/p&gt;

&lt;p&gt;It was the first time for me when I went to a coding conference. Everything was so beautiful and well presented that I couldn't believe my eyes. &lt;/p&gt;

&lt;p&gt;The content was so good that inspired me and made me realize I didn't know React as well as I should.&lt;/p&gt;

&lt;p&gt;So, I was motivated to learn more important things about React, such as the new features and the performance parts and patterns that I didn't know.&lt;/p&gt;

&lt;p&gt;It was this moment that created a question inside my mind: What if I would create a book that describes these topics and also make me learn them in depth?&lt;/p&gt;

&lt;p&gt;And so I did. I present you: &lt;strong&gt;Best Ways to Improve Your React Project&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When. you should and should not &lt;strong&gt;useEffect&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Patterns, like the &lt;strong&gt;Composition&lt;/strong&gt; pattern&lt;/li&gt;
&lt;li&gt;Architecture and folder structure using the &lt;strong&gt;Fractal&lt;/strong&gt; pattern&lt;/li&gt;
&lt;li&gt;Handling modern forms with &lt;strong&gt;RHF&lt;/strong&gt; and &lt;strong&gt;Zod&lt;/strong&gt; for Validation&lt;/li&gt;
&lt;li&gt;Introduction to &lt;strong&gt;React Compiler&lt;/strong&gt; and why you shouldn't memoize manually anymore&lt;/li&gt;
&lt;li&gt;Virtualization&lt;/li&gt;
&lt;li&gt;Using AI in your React workflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useTransition&lt;/strong&gt; and &lt;strong&gt;useOptimistic&lt;/strong&gt; for instant UIs
... and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preview
&lt;/h2&gt;

&lt;p&gt;A free 20 pages preview is available on my website, on book's section: &lt;a href="https://gabrielenache.com" rel="noopener noreferrer"&gt;Free Preview&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where can you find it?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;EPUB&lt;/strong&gt; and &lt;strong&gt;Paperback&lt;/strong&gt; versions on Amazon: &lt;a href="https://www.amazon.com/dp/B0GSD2Q493" rel="noopener noreferrer"&gt;Amazon EPUB &amp;amp; Paperback versions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF&lt;/strong&gt; version and a 40% discount, use code &lt;em&gt;&lt;strong&gt;LAUNCH&lt;/strong&gt;&lt;/em&gt; on Gumroad: &lt;br&gt;
&lt;a href="https://gabrielenache.gumroad.com/l/best-ways-to-improve-your-react-project" rel="noopener noreferrer"&gt;PDF version with 40% discount&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Vite 8 Is Here — And It Changes Everything About Frontend Builds</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Fri, 13 Mar 2026 12:08:35 +0000</pubDate>
      <link>https://dev.to/gabrielenache/vite-8-is-here-and-it-changes-everything-about-frontend-builds-45ci</link>
      <guid>https://dev.to/gabrielenache/vite-8-is-here-and-it-changes-everything-about-frontend-builds-45ci</guid>
      <description>&lt;p&gt;After months of beta testing and community feedback, Vite 8 has officially landed — and it’s the most significant release since Vite rewrote the rules of frontend development. The headline?&lt;/p&gt;

&lt;p&gt;Vite is now powered by Rolldown, a blazing-fast Rust-based bundler built by the same team behind Vite. This isn’t just a performance bump. It’s an architectural shift that sets the stage for the next generation of frontend tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Vite 8 Solves
&lt;/h2&gt;

&lt;p&gt;Before Vite 8, Vite used two separate tools under the hood:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;esbuild — for blazing-fast development server transforms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rollup — for production bundling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This split worked well, but it created an inherent friction: two transformation pipelines, two plugin systems, and subtle behavioral differences between dev and production builds. Debugging “it works in dev but breaks in prod” is a rite of passage no developer should have to endure.&lt;/p&gt;

&lt;p&gt;Vite 8 eliminates this split entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Rolldown: One Bundler to Rule Them All
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://rolldown.rs" rel="noopener noreferrer"&gt;https://rolldown.rs&lt;/a&gt; is a Rust-powered bundler with full compatibility with the Rollup plugin API. With Vite 8, it replaces both esbuild and Rollup in the build pipeline, giving you a single, unified toolchain end-to-end.&lt;/p&gt;

&lt;p&gt;The numbers speak for themselves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In official benchmarks across 19,000 modules, Rolldown completed in 1.61 seconds vs Rollup’s 40.10 seconds — a 25x improvement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linear (the project management tool) reported their production build time dropping from 46 seconds to 6 seconds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Community reports are showing 10–30x faster production builds across a wide range of project sizes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dev server startup is ~3x faster, full reloads are ~40% faster&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is just the beginning. The team is actively working on Full Bundle Mode, which promises 10x fewer network requests during development by shipping a single pre-bundled file instead of individual modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s New in Vite 8
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unified Toolchain
&lt;/h3&gt;

&lt;p&gt;Vite, Rolldown, and Oxc (the Rust-based JS compiler) are now all built and maintained by the same team — VoidZero. This means consistent behavior, tighter integration, and a single team accountable for the full stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Built-in tsconfig Paths Support
&lt;/h3&gt;

&lt;p&gt;No more vite-tsconfig-paths plugin for most setups. Just set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vite.config.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;tsconfigPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;h3&gt;
  
  
  Browser Console Forwarding
&lt;/h3&gt;

&lt;p&gt;You can now forward browser console.log and errors directly to your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;forwardConsole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;Useful for debugging SSR and backend-heavy apps where you want a single unified log stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wasm SSR Support
&lt;/h3&gt;

&lt;p&gt;.wasm?init imports now work in SSR environments — a long-requested feature for teams building with WebAssembly on the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrated Vite Devtools
&lt;/h3&gt;

&lt;p&gt;An opt-in devtools option adds rich in-browser debugging and analysis tooling, giving you deep insight into module graphs, plugin transforms, and build metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lightning CSS for CSS Minification
&lt;/h3&gt;

&lt;p&gt;Vite 8 switches from esbuild to Lightning CSS for CSS minification by default, offering better standards support and smaller output. You can opt back to esbuild if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cssMinify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;esbuild&lt;/span&gt;&lt;span class="dl"&gt;'&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;h3&gt;
  
  
  React Plugin Goes Oxc-Native
&lt;/h3&gt;

&lt;p&gt;@vitejs/plugin-react v6 ships alongside Vite 8. Babel is no longer a dependency — React Refresh transforms now run through Oxc, meaning faster installs and faster HMR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Breaking Changes Worth Knowing
&lt;/h3&gt;

&lt;p&gt;Vite 8 was designed to minimize migration friction, but a few things changed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node.js 20.19+ or 22.12+ is now required — drop anything older&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;esbuild.minify* options moved to build.rolldownOptions.output.minify&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some manual chunk configurations and dependency optimization behaviors have changed — check the &lt;a href="https://vite.dev/guide/migration" rel="noopener noreferrer"&gt;https://vite.dev/guide/migration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plugin authors: most Rollup-compatible plugins work out of the box since Rolldown implements the same plugin API SvelteKit, React Router, and Storybook have all been tested and work without changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Should You Upgrade Now?
&lt;/h3&gt;

&lt;p&gt;Yes, for most projects. The migration path is smooth:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install vite@8 — save-dev&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
For simple projects with minimal custom config, that’s often all you need. For complex setups with heavy plugin usage or manual chunk splitting, review the migration guide and test your production build before deploying.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Bigger Picture
&lt;/h3&gt;

&lt;p&gt;Vite 8 isn’t just a version bump — it’s the first milestone in VoidZero’s vision of a fully unified JavaScript toolchain built in Rust. Vite owns the dev experience. Rolldown owns the bundling. Oxc owns the transforms. They all speak the same language now.&lt;/p&gt;

&lt;p&gt;The JavaScript ecosystem has been plagued by fragmented tooling for years. Vite 8 is a serious step toward ending that era.&lt;/p&gt;

&lt;p&gt;If you haven’t upgraded yet, there’s never been a better time. Your CI pipeline will thank you.&lt;/p&gt;

&lt;p&gt;Have you upgraded to Vite 8 yet? What build time improvements are you seeing? Drop a comment below.&lt;/p&gt;

&lt;p&gt;If you are into React, check my book and my YouTube channel here: &lt;a href="https://gabrielenache.com/" rel="noopener noreferrer"&gt;https://gabrielenache.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Best Ways to Improve Your React Projects (Lessons I Learned the Hard Way)</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Thu, 12 Mar 2026 06:45:45 +0000</pubDate>
      <link>https://dev.to/gabrielenache/the-best-ways-to-improve-your-react-projects-lessons-i-learned-the-hard-way-kh8</link>
      <guid>https://dev.to/gabrielenache/the-best-ways-to-improve-your-react-projects-lessons-i-learned-the-hard-way-kh8</guid>
      <description>&lt;p&gt;After working on multiple React projects—some successful, some painful—I started noticing the same problems appearing again and again.&lt;/p&gt;

&lt;p&gt;Not because React is bad.&lt;br&gt;
But because &lt;strong&gt;most React codebases slowly become messy over time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you've ever opened a React project and thought:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Why is this component 600 lines long?”&lt;/li&gt;
&lt;li&gt;“Why are there 12 useEffects here?”&lt;/li&gt;
&lt;li&gt;“Why is state flowing through 8 components?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're not alone.&lt;/p&gt;

&lt;p&gt;Over the years I collected patterns, refactoring strategies, and architectural ideas that consistently make React projects &lt;strong&gt;simpler, faster, and easier to maintain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Eventually I decided to organize everything into a practical guide.&lt;/p&gt;

&lt;p&gt;👉 You can check it out and even a free sample:&lt;br&gt;
&lt;a href="https://gabrielenache.com" rel="noopener noreferrer"&gt;https://gabrielenache.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But before that, let me share a few of the most important ideas from the book.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Stop Building “Mega Components”
&lt;/h2&gt;

&lt;p&gt;One of the biggest problems in React projects is &lt;strong&gt;component bloat&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A component starts small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then over time it grows to include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls&lt;/li&gt;
&lt;li&gt;validation&lt;/li&gt;
&lt;li&gt;UI logic&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;business logic&lt;/li&gt;
&lt;li&gt;event handlers&lt;/li&gt;
&lt;li&gt;conditional rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly the file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jsx &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;850&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hard to read&lt;/li&gt;
&lt;li&gt;Hard to test&lt;/li&gt;
&lt;li&gt;Hard to reuse&lt;/li&gt;
&lt;li&gt;Hard to debug&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A better pattern
&lt;/h3&gt;

&lt;p&gt;Break logic into &lt;strong&gt;layers&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. UI components&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;UserProfileView
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Hooks&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useUserProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Services&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now each part has a clear responsibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Custom Hooks Are Your Superpower
&lt;/h2&gt;

&lt;p&gt;Many developers underestimate &lt;strong&gt;custom hooks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They are not just for reuse — they are for &lt;strong&gt;architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Instead of this inside a component:&lt;br&gt;
&lt;/p&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="nf"&gt;fetchUser&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;Move the logic into a hook:&lt;br&gt;
&lt;/p&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your component becomes:&lt;br&gt;
&lt;/p&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;Profile&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&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;Spinner&lt;/span&gt; &lt;span class="o"&gt;/&amp;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;UserCard&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&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;Much cleaner.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. State Management Is Often Overcomplicated
&lt;/h2&gt;

&lt;p&gt;I’ve seen projects using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redux&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Zustand&lt;/li&gt;
&lt;li&gt;Recoil&lt;/li&gt;
&lt;li&gt;local state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All at the same time.&lt;/p&gt;

&lt;p&gt;This is usually unnecessary.&lt;/p&gt;

&lt;p&gt;A good rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the simplest state solution possible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Typical order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Local component state&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Lightweight store (Zustand / Jotai)&lt;/li&gt;
&lt;li&gt;Redux (only for complex apps)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most apps &lt;strong&gt;don’t need Redux anymore&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Folder Structure Matters More Than You Think
&lt;/h2&gt;

&lt;p&gt;Bad structure leads to chaos.&lt;/p&gt;

&lt;p&gt;Example of a common messy structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/components
/hooks
/utils
/services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem?&lt;/p&gt;

&lt;p&gt;Your features get &lt;strong&gt;spread across the entire project&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A better approach is &lt;strong&gt;feature-based structure&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;/features
   /auth
      LoginForm.jsx
      useAuth.js
      authService.js

   /dashboard
      Dashboard.jsx
      dashboardService.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now everything related to a feature lives together.&lt;/p&gt;

&lt;p&gt;This makes scaling much easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Performance Problems Often Come From Small Mistakes
&lt;/h2&gt;

&lt;p&gt;Many React performance issues come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unnecessary re-renders&lt;/li&gt;
&lt;li&gt;heavy components&lt;/li&gt;
&lt;li&gt;unstable props&lt;/li&gt;
&lt;li&gt;poorly structured state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Small details like this can make a &lt;strong&gt;huge difference in large applications&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Wrote This Book
&lt;/h2&gt;

&lt;p&gt;I wrote &lt;strong&gt;"Best Ways to Improve Your React Project"&lt;/strong&gt; because most React resources focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;syntax&lt;/li&gt;
&lt;li&gt;hooks basics&lt;/li&gt;
&lt;li&gt;small examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But real-world React projects need more than that.&lt;/p&gt;

&lt;p&gt;They need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;structure&lt;/li&gt;
&lt;li&gt;maintainability&lt;/li&gt;
&lt;li&gt;scalability&lt;/li&gt;
&lt;li&gt;debugging strategies&lt;/li&gt;
&lt;li&gt;refactoring patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of the book is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Help developers turn messy React projects into clean, maintainable systems.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Who This Book Is For
&lt;/h2&gt;

&lt;p&gt;This guide is useful if you are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a React developer working on real projects&lt;/li&gt;
&lt;li&gt;maintaining a growing codebase&lt;/li&gt;
&lt;li&gt;refactoring messy components&lt;/li&gt;
&lt;li&gt;trying to improve project structure&lt;/li&gt;
&lt;li&gt;preparing for senior-level development&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  If You're Curious
&lt;/h2&gt;

&lt;p&gt;You can check out the book here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://gabrielenache.com" rel="noopener noreferrer"&gt;https://gabrielenache.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It includes practical strategies like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React architecture patterns&lt;/li&gt;
&lt;li&gt;component design principles&lt;/li&gt;
&lt;li&gt;refactoring techniques&lt;/li&gt;
&lt;li&gt;state management strategies&lt;/li&gt;
&lt;li&gt;performance improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is focused on &lt;strong&gt;real-world React development&lt;/strong&gt;, not toy examples.&lt;/p&gt;




&lt;p&gt;If you're a React developer, I'm curious:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s the biggest problem you’ve encountered in a React codebase?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Massive components?&lt;br&gt;
State management chaos?&lt;br&gt;
Performance issues?&lt;/p&gt;

&lt;p&gt;Let me know — I’d love to hear your experience.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>codequality</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>You're Overusing useEffect. Here's How to Fix It.</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Wed, 11 Mar 2026 08:51:46 +0000</pubDate>
      <link>https://dev.to/gabrielenache/youre-overusing-useeffect-heres-how-to-fix-it-hef</link>
      <guid>https://dev.to/gabrielenache/youre-overusing-useeffect-heres-how-to-fix-it-hef</guid>
      <description>&lt;p&gt;I'm going to say something controversial: most useEffect calls I see in code reviews don't need to exist.&lt;/p&gt;

&lt;p&gt;Not because the developer wrote bad code. But because useEffect feels like the natural answer to a lot of problems it wasn't actually designed to solve. You need to do something after state changes? useEffect. You need to reset something when a prop changes? useEffect. You need to call a function after a user clicks a button? useEffect.&lt;/p&gt;

&lt;p&gt;I was guilty of all of these. For years. And it wasn't until I really sat down with the React docs — specifically the page called &lt;a href="https://react.dev/learn/you-might-not-need-an-effect" rel="noopener noreferrer"&gt;You Might Not Need an Effect&lt;/a&gt; — that I understood what this hook is actually for.&lt;/p&gt;

&lt;p&gt;This article is a practical breakdown of the most common useEffect misuses I've seen, and exactly what to do instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is useEffect actually for?
&lt;/h2&gt;

&lt;p&gt;Before we get into the anti-patterns, let's be clear about what useEffect is designed for.&lt;/p&gt;

&lt;p&gt;useEffect is for synchronizing your component with an external system. That's it. Browser APIs like &lt;strong&gt;ResizeObserver&lt;/strong&gt;, WebSockets, third-party libraries that need to be set up and torn down, timers that need cleanup — these are legitimate use cases.&lt;/p&gt;

&lt;p&gt;If what you're doing doesn't involve an external system, you probably don't need useEffect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #1: Deriving state from other state or props
&lt;/h2&gt;

&lt;p&gt;This is the most common one. You have some state, you want to compute something from it, and you reach for useEffect to keep them in sync.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Don't do this&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;filteredProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFilteredProducts&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;products&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;setFilteredProducts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inStock&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;products&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;filteredProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;p&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;p&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;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;What's wrong here? This causes &lt;strong&gt;two renders&lt;/strong&gt; instead of one. React renders with the old filteredProducts, then the effect runs, updates the state, and React renders again. You're also storing derived data in state, which is almost always unnecessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Do this instead&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredProducts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inStock&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;filteredProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;p&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;p&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Just compute it during render. One render, no effect, no extra state.&lt;/p&gt;

&lt;p&gt;If the computation is genuinely expensive (sorting 50,000 records, complex transformations), then useMemo is appropriate. But filtering a normal-sized array? Just do it inline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #2: Resetting state when a prop changes
&lt;/h2&gt;

&lt;p&gt;You want to clear a text field when the user switches to a different item. Naturally, you write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Don't do this&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CommentBox&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;postId&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;comment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setComment&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="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;setComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&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;postId&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&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;setComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Same problem as before — an extra render. The component first renders with the stale comment, then the effect fires and clears it, and React renders again.&lt;/p&gt;

&lt;p&gt;The correct solution is one of the most underused tricks in React: the &lt;strong&gt;key&lt;/strong&gt; prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Do this instead&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CommentBox&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;strong&gt;key&lt;/strong&gt; changes, React unmounts the component entirely and mounts a fresh one. All local state resets automatically. No useEffect, no extra render, one line of code.&lt;/p&gt;

&lt;p&gt;I use this trick constantly. Once you know about it, you'll see opportunities for it everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #3: Reacting to user events inside useEffect
&lt;/h2&gt;

&lt;p&gt;This one looks obviously wrong when you see it written out, but I've seen it more times than I can count:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Don't do this&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&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;submitted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSubmitted&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="kc"&gt;false&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;submitted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;onSuccess&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;submitted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&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;setSubmitted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Submit&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Why would you do this? If something needs to happen because the user clicked a button, put it in the click handler. That's what click handlers are for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Do this instead&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&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="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&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;onSuccess&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Submit&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;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;The rule is simple: if it's caused by a user action, handle it in an event handler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #4: Effect chains
&lt;/h2&gt;

&lt;p&gt;This is where things get really messy. One &lt;strong&gt;useEffect&lt;/strong&gt; sets some state, which triggers another useEffect, which sets more state, which triggers another...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ A chain of effects — a debugging nightmare&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoadingUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setIsLoadingUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculatePermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setNavItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;buildNavigation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;permissions&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every link in this chain adds another render cycle. You have cascading state updates, potential race conditions, and code that's nearly impossible to trace when something goes wrong.&lt;/p&gt;

&lt;p&gt;If you find yourself in this situation, step back and ask: can I compute this in a single place?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Derive everything from the source of truth&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userId&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="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&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;permissions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculatePermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&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;navItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildNavigation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setNavItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;navItems&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or better yet — use &lt;a href="https://tanstack.com/query/latest" rel="noopener noreferrer"&gt;TanStack Query&lt;/a&gt; and get rid of the manual loading state management entirely (more on that below).&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake #5: Fetching data without proper cleanup
&lt;/h2&gt;

&lt;p&gt;Data fetching is one of the legitimate uses of useEffect. But most implementations you'll find in the wild are broken in a subtle way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ This has a race condition&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&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;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;userId&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;user&lt;/span&gt; &lt;span class="p"&gt;?&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;user&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt; : &amp;lt;p&amp;gt;Loading...&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;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;The problem: if userId changes before the first fetch resolves, both requests are in flight simultaneously. Whichever finishes last wins. You might render data for the wrong user.&lt;/p&gt;

&lt;p&gt;The fix is to ignore stale responses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ With cleanup — ignores stale responses&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;let&lt;/span&gt; &lt;span class="nx"&gt;cancelled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cancelled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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="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;cancelled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But honestly? In 2026, you shouldn't be writing raw data fetching in useEffect at all. Use TanStack Query. It handles caching, deduplication, cancellation, and background refetching out of the box. You literally can't forget the cleanup because the library handles it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Just use TanStack Query&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-query&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;UserCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;queryKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;queryFn&lt;/span&gt;&lt;span class="p"&gt;:&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;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&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;/p&amp;gt; : &amp;lt;div&amp;gt;{user&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;.name}&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No cleanup, no race conditions, automatic caching, background refetching when you return to the tab. It's not even a close comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  So when DO you need useEffect?
&lt;/h2&gt;

&lt;p&gt;Here's the short list of genuinely appropriate useEffect uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up a WebSocket connection and cleaning it up on unmount&lt;/li&gt;
&lt;li&gt;Subscribing to a browser API like ResizeObserver, IntersectionObserver, or addEventListener&lt;/li&gt;
&lt;li&gt;Integrating a third-party library that directly manipulates the DOM (like a chart library or map)&lt;/li&gt;
&lt;li&gt;Syncing with localStorage or sessionStorage on mount&lt;/li&gt;
&lt;li&gt;Analytics page view tracking when a route changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice the pattern: all of these involve talking to something outside of React. That's the rule. If you're only dealing with React state and props, you probably don't need useEffect.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rules I follow
&lt;/h2&gt;

&lt;p&gt;Let me summarize with the practical rules I've internalized:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you can compute it during render, don't store it in state. Derived values belong in the render function, not in state + useEffect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it's triggered by a user event, handle it in the event handler. onClick, onChange, onSubmit — these are where your logic belongs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you need to reset state when a prop changes, use the key prop. Not useEffect. Just change the key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you're fetching data, use TanStack Query or SWR. Don't reinvent this with raw useEffect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you're synchronizing with an external system, useEffect is correct. That's literally what it's for.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;useEffect is a powerful hook that gets misused because it seems like the right tool for so many problems. But most of the time, the real solution is simpler: compute during render, handle events in handlers, or use a library that's designed for the specific problem you're solving.&lt;/p&gt;

&lt;p&gt;Once you internalize these rules, you'll find your components getting smaller, faster, and much easier to debug. The double renders disappear. The cascading state updates disappear. The race conditions disappear.&lt;/p&gt;

&lt;p&gt;It's one of those things where less code genuinely means better code.&lt;/p&gt;




&lt;p&gt;This article is based on a chapter from my book "Best Ways to Improve Your React Project — 2026 Edition" — a guide for mid-to-senior React developers covering architecture, patterns, performance, React 19 APIs, testing, and more.&lt;/p&gt;

&lt;p&gt;If you found this useful, the book has 13 more chapters like it.&lt;/p&gt;

&lt;p&gt;→ PDF on Gumroad (use code LAUNCH for a 40% launch discount): &lt;a href="https://gabrielenache.gumroad.com/l/best-ways-to-improve-your-react-project" rel="noopener noreferrer"&gt;https://gabrielenache.gumroad.com/l/best-ways-to-improve-your-react-project&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>The MERN Stack SaaS Guide</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Mon, 09 Mar 2026 11:48:52 +0000</pubDate>
      <link>https://dev.to/gabrielenache/the-mern-stack-saas-guide-2kae</link>
      <guid>https://dev.to/gabrielenache/the-mern-stack-saas-guide-2kae</guid>
      <description>&lt;p&gt;I wrote a &lt;em&gt;&lt;strong&gt;MERN SaaS Starter Guide&lt;/strong&gt;&lt;/em&gt; on GitHub and I want to share it with you for FREE.&lt;/p&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Best Libraries to use&lt;/li&gt;
&lt;li&gt;Setup&lt;/li&gt;
&lt;li&gt;Deployment steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contributors are welcome! 100% open source!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/eIonut/MERN-SaaS-Starter-Guide" rel="noopener noreferrer"&gt;https://github.com/eIonut/MERN-SaaS-Starter-Guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>Composition Pattern in React</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Sat, 07 Mar 2026 15:38:32 +0000</pubDate>
      <link>https://dev.to/gabrielenache/composition-pattern-in-react-1i52</link>
      <guid>https://dev.to/gabrielenache/composition-pattern-in-react-1i52</guid>
      <description>&lt;h2&gt;
  
  
  What is composition in React?
&lt;/h2&gt;

&lt;p&gt;Composition is a pattern where components are tied up together like building blocks to create complex UIs.&lt;/p&gt;

&lt;p&gt;Instead of relying too much on props and foul yourself that if you add one more prop the component will then be more customizable, you should always try to use this pattern whenever possible to avoid and minimize the amount of props your component has.&lt;/p&gt;

&lt;p&gt;Take a look at the following &lt;strong&gt;&lt;em&gt;ConfiguredModal.tsx&lt;/em&gt;&lt;/strong&gt; component, starting with the necessary types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type ConfiguredModalProps = {
  isOpen: boolean;
  onClose: () =&amp;gt; void;
  title?: string;
  withDelimiter?: boolean;
  withFooter?: boolean;
  children: React.ReactNode;
  headerActions?: () =&amp;gt; React.ReactNode; // edit button, download
// ... more props
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the sake of simplicity and to not scare you with too much CSS, I will hide the &lt;em&gt;&lt;strong&gt;className&lt;/strong&gt;&lt;/em&gt; attributes from all the elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function ConfiguredModal({
  isOpen,
  onClose,
  headerActions,
  title,
  withDelimiter,
  withFooter,
  children,
}: ConfiguredModalProps) {
  if (!isOpen) return null;

  return (
    &amp;lt;div aria-modal="true" role="dialog" onClick={onClose}&amp;gt;
      &amp;lt;div onClick={(e) =&amp;gt; e.stopPropagation()}&amp;gt;
        &amp;lt;button onClick={onClose}&amp;gt;
          &amp;lt;CircleX /&amp;gt;
        &amp;lt;/button&amp;gt;

        &amp;lt;div&amp;gt;
          {title &amp;amp;&amp;amp; &amp;lt;h2&amp;gt;{title}&amp;lt;/h2&amp;gt;}
          {headerActions ? headerActions() : null}
        &amp;lt;/div&amp;gt;

        &amp;lt;div&amp;gt;{children}&amp;lt;/div&amp;gt;

        {withDelimiter &amp;amp;&amp;amp; (
          &amp;lt;span&amp;gt;
            &amp;lt;hr /&amp;gt;
          &amp;lt;/span&amp;gt;
        )}

        {withFooter &amp;amp;&amp;amp; (
          &amp;lt;footer&amp;gt;
            &amp;lt;PrimaryButton onClick={() =&amp;gt; console.log("Confirm clicked")}&amp;gt;
              Confirm
            &amp;lt;/PrimaryButton&amp;gt;
          &amp;lt;/footer&amp;gt;
        )}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you probably noticed, this component has a lot of props, even if it doesn't look like it, because you would say: "Huh, 7 props are not many, right?". Well… that depends. By just looking at the code, this component is very hard to read. And also, even on the consumer part, it looks tedious with all these props:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ConfiguredModal
  title="My Modal Title"
  isOpen={isOpen}
  onClose={() =&amp;gt; setIsOpen(false)}
  withDelimiter
  headerActions={() =&amp;gt; (
    &amp;lt;div&amp;gt;
      &amp;lt;PrimaryButton
        variant="outlined"
        onClick={() =&amp;gt; console.log("Edit clicked")}
      &amp;gt;
        Edit
      &amp;lt;/PrimaryButton&amp;gt;
      &amp;lt;PrimaryButton
        variant="outlined"
        onClick={() =&amp;gt; console.log("Download clicked")}
      &amp;gt;
        Download
      &amp;lt;/PrimaryButton&amp;gt;
    &amp;lt;/div&amp;gt;
  )}
  withFooter
&amp;gt;
  &amp;lt;p&amp;gt;Some text..&amp;lt;/p&amp;gt;
&amp;lt;/ConfiguredModal&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if this is technically correct, we have too many conditionals: If title exists, then display title. If there is a HeaderActions component that should be displayed just display it or return null, show a delimiter if withDelimiter is provided or it's true, same for the footer.&lt;/p&gt;

&lt;p&gt;Wouldn't it be nice if we would have a nice way to keep the same functionalities, but with a more readable and composable component?&lt;br&gt;
Well, fortunately, there is a way.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Donut pattern in practice
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;"Donut pattern"&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;"The composition pattern"&lt;/em&gt;&lt;/strong&gt; is one of the most fundamental yet important patterns in building complex UI. It removes the configuration needs(adding more props) and it promotes composition as its root technique. To see this pattern in action, I created the optimized composed version of the &lt;strong&gt;&lt;em&gt;ConfiguredModal.tsx&lt;/em&gt;&lt;/strong&gt;, which resides in the &lt;strong&gt;&lt;em&gt;ComposedModal.tsx&lt;/em&gt;&lt;/strong&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function ComposedModal({
  isOpen,
  onClose,
  children,
}: ComposedModalProps) {
  return (
    isOpen &amp;amp;&amp;amp; (
      &amp;lt;div aria-modal="true" role="dialog" onClick={onClose}&amp;gt;
        &amp;lt;div onClick={(e) =&amp;gt; e.stopPropagation()}&amp;gt;
          &amp;lt;button onClick={onClose}&amp;gt;
            &amp;lt;CircleX /&amp;gt;
          &amp;lt;/button&amp;gt;
          {children}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks much clearer, right? We only keep the "skeleton" of our modal inside the component, but the interesting part comes next. Now that we defined the basic functionality of the modal, it's time to define it's parts and components like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type HeaderProps = {
  title: string,
  children: React.ReactNode,
};

function Header({ title, children }: HeaderProps) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h2&amp;gt;{title}&amp;lt;/h2&amp;gt;
      &amp;lt;div&amp;gt;{children}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

function Body({ children }: { children: React.ReactNode }) {
  return &amp;lt;div&amp;gt;{children}&amp;lt;/div&amp;gt;;
}

function Footer({ children }: { children: React.ReactNode }) {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;span&amp;gt;
        &amp;lt;hr /&amp;gt;
      &amp;lt;/span&amp;gt;
      &amp;lt;footer&amp;gt;{children}&amp;lt;/footer&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

ComposedModal.Header = Header;
ComposedModal.Body = Body;
ComposedModal.Footer = Footer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We tell React that our &lt;em&gt;&lt;strong&gt;ComposedModal&lt;/strong&gt;&lt;/em&gt; can have 3 parts: A &lt;strong&gt;&lt;em&gt;Header&lt;/em&gt;&lt;/strong&gt;, a &lt;strong&gt;&lt;em&gt;Body&lt;/em&gt;&lt;/strong&gt;, and a &lt;strong&gt;&lt;em&gt;Footer&lt;/em&gt;&lt;/strong&gt;. For this, we write a simple component for each part of the modal, where we basically only define the required structure of the respective component. We basically tell the consumer: "We give you the structure that we want, but you can put anything in there and style it however you want".&lt;/p&gt;

&lt;p&gt;This way, we ensure that the "final" component will be composable and we give the user the power to choose if they want to display a certain part of the modal or not by simply not putting anything in there.&lt;/p&gt;

&lt;p&gt;Now, on the consumer part, the code is a lot clearer and it looks like a donut, because the consumer places everything that he needs as children, but in a structured and composed way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function ExamplePage() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setIsOpen(true)}&amp;gt;Open Modal&amp;lt;/button&amp;gt;
      &amp;lt;ComposedModal isOpen={isOpen} onClose={() =&amp;gt; setIsOpen(false)}&amp;gt;
        &amp;lt;ComposedModal.Header title="My modal title"&amp;gt;
          &amp;lt;div&amp;gt;
            &amp;lt;PrimaryButton
              variant="outlined"
              onClick={() =&amp;gt; console.log("Edit clicked")}
            &amp;gt;
              Edit
            &amp;lt;/PrimaryButton&amp;gt;
            &amp;lt;PrimaryButton
              variant="outlined"
              onClick={() =&amp;gt; console.log("Download clicked")}
            &amp;gt;
              Download
            &amp;lt;/PrimaryButton&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/ComposedModal.Header&amp;gt;
        &amp;lt;ComposedModal.Body&amp;gt;
          &amp;lt;p&amp;gt;Some text...&amp;lt;/p&amp;gt;
        &amp;lt;/ComposedModal.Body&amp;gt;
        &amp;lt;ComposedModal.Footer&amp;gt;
          &amp;lt;PrimaryButton onClick={() =&amp;gt; console.log("Confirm clicked")}&amp;gt;
            Confirm
          &amp;lt;/PrimaryButton&amp;gt;
        &amp;lt;/ComposedModal.Footer&amp;gt;
      &amp;lt;/ComposedModal&amp;gt;
    &amp;lt;/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>react</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Conditional Rendering Caveats in React</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Sat, 07 Mar 2026 14:50:10 +0000</pubDate>
      <link>https://dev.to/gabrielenache/conditional-rendering-caveats-in-react-odj</link>
      <guid>https://dev.to/gabrielenache/conditional-rendering-caveats-in-react-odj</guid>
      <description>&lt;p&gt;When components need to display different things depending on different conditions, typically we would use the &amp;amp;&amp;amp;(logical and) operator.&lt;/p&gt;

&lt;p&gt;Say we have a list or products and we want to display our list of products in JSX and therefore, on our web page. Pretty easy, right? Now… what happens if the list of products is empty?&lt;/p&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%2F9rbluljsno0iibrv1nrz.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%2F9rbluljsno0iibrv1nrz.png" alt="Using the &amp;amp;&amp;amp; operator" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the &amp;amp;&amp;amp; operator, as you would have probably guessed, 0 is rendered on the page. That's because when Javascript evaluates products.length which is 0 with anything else, the whole result of the expression will be 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the conditional(ternary operator) so you can explicitly tell JSX what to render based on a true or false expression.&lt;br&gt;
Using the ternary operator&lt;/p&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%2Fsdwwux9udeizrc5pu02c.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%2Fsdwwux9udeizrc5pu02c.png" alt="Using the ternary operator" width="800" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Used v0 as a Figma Replacement, Not a Code Generator — Here's the Workflow</title>
      <dc:creator>Gabriel-Ionut Enache</dc:creator>
      <pubDate>Sat, 14 Feb 2026 11:32:05 +0000</pubDate>
      <link>https://dev.to/gabrielenache/i-used-v0-as-a-figma-replacement-not-a-code-generator-heres-the-workflow-a44</link>
      <guid>https://dev.to/gabrielenache/i-used-v0-as-a-figma-replacement-not-a-code-generator-heres-the-workflow-a44</guid>
      <description>&lt;p&gt;I'm building &lt;strong&gt;&lt;a href="https://homeafford.io" rel="noopener noreferrer"&gt;HomeAfford&lt;/a&gt;&lt;/strong&gt;, a mortgage affordability calculator, in Next.js with TypeScript and Tailwind CSS.&lt;/p&gt;

&lt;p&gt;Before writing any code, I prompted v0 by Vercel to generate the full UI: landing page, calculator interface, pricing page, and feature sections. The result looked great — clean layout, solid component&lt;br&gt;
  structure, good visual hierarchy.&lt;/p&gt;

&lt;p&gt;Then I looked at the code.&lt;/p&gt;

&lt;p&gt;Everything was calculated on the frontend. The code was messy. Files were huge.&lt;/p&gt;

&lt;p&gt;So I made a decision: keep the design, rewrite the code.&lt;/p&gt;

&lt;p&gt;I treated v0's output exactly like a Figma mockup — a visual reference, not a codebase. Then I built four things from scratch:&lt;/p&gt;

&lt;p&gt;** 1. Landing page — based on v0's layout but with real components&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google authentication — not generated by v0 at all&lt;/li&gt;
&lt;li&gt;Mortgage calculator — actual math, real inputs, dynamic results&lt;/li&gt;
&lt;li&gt;Pricing page — connected to real tier logic**&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The 3-step workflow I'm using going forward
&lt;/h2&gt;

&lt;p&gt;**1. Design with AI — use v0/similar tools to explore layouts fast&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluate the output — keep what works visually, ignore the code&lt;/li&gt;
&lt;li&gt;Build it yourself — use the design as a reference and write production code**&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This isn't an anti-AI take. v0 genuinely saved me time I would've spent in Figma. But knowing where AI helps and where it doesn't is the skill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I recorded the full process: &lt;a href="https://youtube.com/watch?v=YvLX88Fr-y0" rel="noopener noreferrer"&gt;https://youtube.com/watch?v=YvLX88Fr-y0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the first in a series building HomeAfford from scratch. Next up: the technical deep dive into the calculator logic.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
