[{"data":1,"prerenderedAt":157},["ShallowReactive",2],{"blog-tech-react":3},[4,23,39,54,68,82,97,113,127,142],{"id":5,"slug":6,"title":7,"subtitle":8,"shortDescription":9,"description":10,"featureImage":11,"category":12,"tags":13,"author":18,"publishedDate":19,"featured":20,"relatedPosts":21,"tech":22},201,"react-server-components-complete-guide","React Server Components (RSC): The Complete Guide 2025","Zero bundle size, direct database access, and the future of React","Master React Server Components – learn how to reduce JavaScript bundle size, access backend resources directly, and build faster apps with the RSC architecture. Includes Next.js App Router patterns.","\u003Ch2>Table of Contents\u003C\u002Fh2>\u003Cul>\u003Cli>What Are React Server Components?\u003C\u002Fli>\u003Cli>Client vs Server Components\u003C\u002Fli>\u003Cli>When to Use Each\u003C\u002Fli>\u003Cli>Data Fetching Patterns\u003C\u002Fli>\u003Cli>Performance Impact\u003C\u002Fli>\u003Cli>Common Mistakes\u003C\u002Fli>\u003Cli>Interview Q&A\u003C\u002Fli>\u003Cli>FAQ\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>What Are React Server Components?\u003C\u002Fh2>\u003Cp>React Server Components (RSC) let you write components that run \u003Cstrong>only on the server\u003C\u002Fstrong>. They never send JavaScript to the client – only their rendered output (like HTML). This means zero bundle size for those components.\u003C\u002Fp>\u003Ch2>Client vs Server Components\u003C\u002Fh2>\u003Cp>\u003Cstrong>Server Components\u003C\u002Fstrong> can access databases, filesystems, or any backend resource directly. They cannot use useState, useEffect, or browser APIs. \u003Cstrong>Client Components\u003C\u002Fstrong> are what we've always used – they hydrate and run in the browser.\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-jsx\">\u002F\u002F ServerComponent.server.jsx – runs only on server\nexport default async function ServerComponent() {\n  const data = await db.query('SELECT * FROM users');\n  return &lt;div&gt;{data.map(...)}&lt;\u002Fdiv&gt;;\n}\n\n\u002F\u002F App.jsx – mixing both\nimport ClientCounter from '.\u002FClientCounter.client';\nimport ServerComponent from '.\u002FServerComponent.server';\n\nexport default function Page() {\n  return (\n    &lt;div&gt;\n      &lt;ServerComponent \u002F&gt;  {\u002F* zero JS sent *\u002F}\n      &lt;ClientCounter \u002F&gt;    {\u002F* interactive *\u002F}\n    &lt;\u002Fdiv&gt;\n  );\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Impact\u003C\u002Fh2>\u003Cp>RSC dramatically reduces bundle size – sometimes by 60-80%. Large rendering logic, heavy dependencies (date-fns, lodash) stay on the server. First Contentful Paint improves by 30-50% in typical apps.\u003C\u002Fp>\u003Ch2>Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Putting client hooks (useState) in Server Components – error\u003C\u002Fli>\u003Cli>Forgetting the 'use client' directive for client components\u003C\u002Fli>\u003Cli>Trying to use localStorage or window in Server Components\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: Can Server Components re-render?\u003C\u002Fstrong> Yes, but on the server via navigation or refetch. They don't re-render on client.\u003Cbr>\u003Cstrong>Q: How do Server Components communicate with Client Components?\u003C\u002Fstrong> Via props – you can pass serializable data down, or use context with a provider boundary.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>RSC is the biggest shift in React since hooks. Adopt gradually: start with static pages, then data-heavy lists, finally full migration. Pair with Next.js App Router for production.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Frsc-guide-cover.jpg","React",[12,14,15,16,17],"Server Components","Next.js","Performance","React 19","Sarah Chen","2025-04-10",true,[],"react",{"id":24,"slug":25,"title":26,"subtitle":27,"shortDescription":28,"description":29,"featureImage":30,"category":31,"tags":32,"author":35,"publishedDate":36,"featured":37,"relatedPosts":38,"tech":22},202,"zustand-state-management-mastery","Zustand Mastery: The Minimal State Manager for React","Why Zustand beats Redux and Context for 90% of apps","Learn Zustand from zero to hero – simple API, no boilerplate, perfect TypeScript support, and production-ready patterns. Includes middleware, persistence, and testing.","\u003Ch2>Why Zustand?\u003C\u002Fh2>\u003Cp>Zustand is a small, fast, and scalable state management library. Unlike Redux, there's no providers, actions, reducers, or dispatch. Unlike Context, it doesn't cause unnecessary re-renders. Just a hook.\u003C\u002Fp>\u003Ch2>Basic Store\u003C\u002Fh2>\u003Cpre>\u003Ccode class=\"language-typescript\">import { create } from 'zustand';\n\ninterface BearState {\n  bears: number;\n  increase: () => void;\n  removeAll: () => void;\n}\n\nconst useBearStore = create\u003CBearState>((set) => ({\n  bears: 0,\n  increase: () => set((state) => ({ bears: state.bears + 1 })),\n  removeAll: () => set({ bears: 0 }),\n}));\n\n\u002F\u002F Usage in component\nfunction BearCounter() {\n  const bears = useBearStore((state) => state.bears);\n  const increase = useBearStore((state) => state.increase);\n  return &lt;div&gt;{bears}&lt;button onClick={increase}&gt;+&lt;\u002Fbutton&gt;&lt;\u002Fdiv&gt;;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Production Pattern: Slice Pattern\u003C\u002Fh2>\u003Cpre>\u003Ccode>const createUserSlice = (set) => ({ user: null, setUser: (user) => set({ user }) });\nconst createCartSlice = (set) => ({ cart: [], addItem: (item) => set((state) => ({ cart: [...state.cart, item] })) });\n\nconst useStore = create((...a) => ({\n  ...createUserSlice(...a),\n  ...createCartSlice(...a),\n}));\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Tips\u003C\u002Fh2>\u003Cul>\u003Cli>Use selectors to avoid re-renders: \u003Ccode>const bears = useBearStore(state => state.bears)\u003C\u002Fcode> instead of destructuring whole store.\u003C\u002Fli>\u003Cli>Use shallow equality for nested objects: \u003Ccode>import { shallow } from 'zustand\u002Fshallow'\u003C\u002Fcode>\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: How does Zustand prevent unnecessary re-renders?\u003C\u002Fstrong> It uses strict equality checks by default – only re-renders when selected slice changes.\u003Cbr>\u003Cstrong>Q: Can Zustand handle async actions?\u003C\u002Fstrong> Yes – just make the action async and call set when done.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>Zustand is the best state manager for most React apps. It's simple, performant, and scales from small to large.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Fzustand-mastery.jpg","State Management",[33,31,12,34],"Zustand","TypeScript","Michael Okonkwo","2025-04-05",false,[],{"id":40,"slug":41,"title":42,"subtitle":43,"shortDescription":44,"description":45,"featureImage":46,"category":47,"tags":48,"author":51,"publishedDate":52,"featured":37,"relatedPosts":53,"tech":22},203,"react-router-v6-deep-dive","React Router v6: Deep Dive into Modern Routing","Loaders, actions, error boundaries, and nested routes","Master React Router v6 with data loading, mutations, and advanced patterns. Build production-grade routing with authentication, lazy loading, and route protection.","\u003Ch2>What's New in v6\u003C\u002Fh2>\u003Cp>React Router v6 introduced a completely new data API: loaders, actions, and error boundaries. Routes become self-contained with data fetching and mutations.\u003C\u002Fp>\u003Ch2>Basic Setup\u003C\u002Fh2>\u003Cpre>\u003Ccode>import { createBrowserRouter, RouterProvider } from 'react-router-dom';\n\nconst router = createBrowserRouter([\n  {\n    path: '\u002F',\n    element: &lt;Root \u002F&gt;,\n    loader: rootLoader,\n    children: [\n      { index: true, element: &lt;Home \u002F&gt; },\n      { path: 'contact\u002F:id', element: &lt;Contact \u002F&gt;, loader: contactLoader },\n    ],\n  },\n]);\n\nfunction App() { return &lt;RouterProvider router={router} \u002F&gt;; }\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Loaders and Actions\u003C\u002Fh2>\u003Cpre>\u003Ccode>\u002F\u002F loader runs before rendering\nexport async function contactLoader({ params }) {\n  const contact = await fetchContact(params.id);\n  return { contact };\n}\n\n\u002F\u002F action handles form submissions\nexport async function action({ request, params }) {\n  const formData = await request.formData();\n  await updateContact(params.id, formData);\n  return redirect(`\u002Fcontact\u002F${params.id}`);\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Tips\u003C\u002Fh2>\u003Cul>\u003Cli>Use lazy loading for route components: \u003Ccode>lazy: () => import('.\u002Froutes\u002FContact')\u003C\u002Fcode>\u003C\u002Fli>\u003Cli>Implement route-level code splitting with \u003Ccode>React.lazy\u003C\u002Fcode>\u003C\u002Fli>\u003Cli>Avoid nesting too deep – max 3-4 levels for maintainability\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Forgetting to use \u003Ccode>&lt;Outlet \u002F&gt;\u003C\u002Fcode> for nested routes\u003C\u002Fli>\u003Cli>Not handling loader errors – use \u003Ccode>errorElement\u003C\u002Fcode>\u003C\u002Fli>\u003Cli>Mutating data without actions – leads to stale UI\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: Difference between \u003Ccode>useNavigate\u003C\u002Fcode> and \u003Ccode>&lt;Link&gt;\u003C\u002Fcode>?\u003C\u002Fstrong> Link is declarative for navigation, useNavigate is imperative (after async operations).\u003Cbr>\u003Cstrong>Q: How does React Router handle code splitting?\u003C\u002Fstrong> Use \u003Ccode>lazy\u003C\u002Fcode> property in route object with React.lazy.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>React Router v6 is the most powerful routing library for React. Master loaders\u002Factions for data-driven apps.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Freact-router-v6.jpg","React Router",[47,49,50,12],"Routing","SPA","David Kim","2025-03-28",[],{"id":55,"slug":56,"title":57,"subtitle":58,"shortDescription":59,"description":60,"featureImage":61,"category":12,"tags":62,"author":65,"publishedDate":66,"featured":20,"relatedPosts":67,"tech":22},204,"react-useTransition-useDeferredValue-guide","useTransition and useDeferredValue: Taming Expensive Renders","Keep your app responsive during heavy UI updates","Learn React's concurrent rendering features – useTransition for marking non-urgent updates, useDeferredValue for deferring expensive re-renders. Practical examples and performance measurements.","\u003Ch2>Why Concurrent Features?\u003C\u002Fh2>\u003Cp>React 18 introduced concurrent rendering. Instead of blocking the main thread for expensive updates, you can mark some updates as 'transition' – letting urgent updates (like typing) jump ahead.\u003C\u002Fp>\u003Ch2>useTransition Example\u003C\u002Fh2>\u003Cpre>\u003Ccode>import { useTransition, useState } from 'react';\n\nfunction SearchPage() {\n  const [isPending, startTransition] = useTransition();\n  const [query, setQuery] = useState('');\n  const [results, setResults] = useState([]);\n\n  function handleChange(e) {\n    const value = e.target.value;\n    setQuery(value); \u002F\u002F urgent\n    startTransition(() => {\n      \u002F\u002F non-urgent: expensive filtering\n      const filtered = filterLargeList(value);\n      setResults(filtered);\n    });\n  }\n\n  return (\n    &lt;div&gt;\n      &lt;input value={query} onChange={handleChange} \u002F&gt;\n      {isPending && &lt;Spinner \u002F&gt;}\n      &lt;Results data={results} \u002F&gt;\n    &lt;\u002Fdiv&gt;\n  );\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>useDeferredValue Example\u003C\u002Fh2>\u003Cpre>\u003Ccode>const [query, setQuery] = useState('');\nconst deferredQuery = useDeferredValue(query);\n\u002F\u002F deferredQuery updates lag behind query\n\u002F\u002F perfect for expensive child components\n\nreturn &lt;ExpensiveList searchTerm={deferredQuery} \u002F&gt;;\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Impact\u003C\u002Fh2>\u003Cp>Without transitions, typing into an input that filters 10,000 items would feel janky. With useTransition, typing stays smooth – the expensive filter runs in the background.\u003C\u002Fp>\u003Ch2>Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Wrapping every state update in startTransition – overuse adds overhead\u003C\u002Fli>\u003Cli>Not showing pending indicator – users may think app is broken\u003C\u002Fli>\u003Cli>Using with synchronous external stores – requires useSyncExternalStore\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: Difference between useTransition and useDeferredValue?\u003C\u002Fstrong> useTransition gives you a pending flag and control over which update is urgent. useDeferredValue just gives you a delayed value without flag.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>Use useTransition for user-triggered updates (search, tabs, navigation). Use useDeferredValue for props that come from parent.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Fconcurrent-react.jpg",[12,63,16,64],"Concurrent","useTransition","Elena Rossi","2025-04-12",[],{"id":69,"slug":70,"title":71,"subtitle":72,"shortDescription":73,"description":74,"featureImage":75,"category":12,"tags":76,"author":79,"publishedDate":80,"featured":37,"relatedPosts":81,"tech":22},205,"react-suspense-data-fetching-patterns","React Suspense for Data Fetching: The Complete Guide","Declarative loading states and error boundaries","Master React Suspense with data fetching libraries like Relay, Next.js, or custom solutions. Learn to build seamless loading UX without waterfall requests.","\u003Ch2>What is Suspense?\u003C\u002Fh2>\u003Cp>Suspense lets components 'wait' for something before rendering – traditionally code splitting, now also data fetching. You wrap a component in \u003Ccode>&lt;Suspense fallback={...}&gt;\u003C\u002Fcode>, and React handles loading states automatically.\u003C\u002Fp>\u003Ch2>Basic Usage\u003C\u002Fh2>\u003Cpre>\u003Ccode>import { Suspense } from 'react';\nimport UserProfile from '.\u002FUserProfile';\n\nfunction App() {\n  return (\n    &lt;Suspense fallback={&lt;LoadingSpinner \u002F&gt;}&gt;\n      &lt;UserProfile userId={123} \u002F&gt;\n    &lt;\u002FSuspense&gt;\n  );\n}\n\n\u002F\u002F UserProfile internally throws a promise to suspend\nfunction UserProfile({ userId }) {\n  const user = useSuspenseQuery(userId); \u002F\u002F from Relay or custom\n  return &lt;div&gt;{user.name}&lt;\u002Fdiv&gt;;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Custom Suspense Hook (Advanced)\u003C\u002Fh2>\u003Cpre>\u003Ccode>function useSuspenseData(url) {\n  const ref = useRef();\n  if (!ref.current) {\n    throw fetchData(url).then(result => ref.current = result);\n  }\n  return ref.current;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Tips\u003C\u002Fh2>\u003Cul>\u003Cli>Avoid nested Suspense boundaries unless necessary – each adds overhead\u003C\u002Fli>\u003Cli>Use Suspense with React.lazy for code splitting\u003C\u002Fli>\u003Cli>Combine with ErrorBoundary for graceful failures\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Not having a fallback – blank screen during loading\u003C\u002Fli>\u003Cli>Putting Suspense too high – entire page shows loading\u003C\u002Fli>\u003Cli>Forgetting error boundaries – unhandled promise rejections\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: How does Suspense avoid waterfall requests?\u003C\u002Fstrong> By letting components declare their data needs – React can fetch in parallel before rendering.\u003Cbr>\u003Cstrong>Q: Can I use Suspense without a library?\u003C\u002Fstrong> Yes, implement a promise-cache pattern.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>Suspense + error boundaries create a robust loading\u002Ferror UX. Start with React.lazy, then adopt data Suspense with Relay or Next.js.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Freact-suspense.jpg",[77,78,12,16],"Suspense","Data Fetching","James Liu","2025-04-08",[],{"id":83,"slug":84,"title":85,"subtitle":86,"shortDescription":87,"description":88,"featureImage":89,"category":17,"tags":90,"author":94,"publishedDate":95,"featured":20,"relatedPosts":96,"tech":22},206,"react-19-actions-useoptimistic","React 19 Actions and useOptimistic: The Future of Forms","Automatic pending states, optimistic updates, and form handling","Explore React 19's new Actions API, useOptimistic, useFormStatus, and how they simplify form submissions, mutations, and real-time UI updates.","\u003Ch2>What Are Actions?\u003C\u002Fh2>\u003Cp>React 19 introduces Actions – async functions passed to \u003Ccode>action\u003C\u002Fcode> prop on \u003Ccode>&lt;form&gt;\u003C\u002Fcode>. React manages pending states, errors, and optimistic updates automatically.\u003C\u002Fp>\u003Ch2>Basic Form Action\u003C\u002Fh2>\u003Cpre>\u003Ccode>function UpdateName() {\n  async function updateName(formData) {\n    const name = formData.get('name');\n    await updateUser(name);\n  }\n\n  return (\n    &lt;form action={updateName}&gt;\n      &lt;input name=\"name\" \u002F&gt;\n      &lt;button type=\"submit\"&gt;Update&lt;\u002Fbutton&gt;\n    &lt;\u002Fform&gt;\n  );\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>useOptimistic Hook\u003C\u002Fh2>\u003Cpre>\u003Ccode>function Thread({ messages, sendMessage }) {\n  const [optimisticMessages, addOptimistic] = useOptimistic(\n    messages,\n    (state, newMsg) => [...state, { ...newMsg, sending: true }]\n  );\n\n  async function formAction(formData) {\n    const message = formData.get('message');\n    addOptimistic({ text: message });\n    await sendMessage(message);\n  }\n\n  return (\n    &lt;&gt;\n      {optimisticMessages.map(m => &lt;Message key={m.id} {...m} \u002F&gt;)}\n      &lt;form action={formAction}&gt;&lt;input name=\"message\" \u002F&gt;&lt;\u002Fform&gt;\n    &lt;\u002F&gt;\n  );\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>useFormStatus (in child components)\u003C\u002Fh2>\u003Cpre>\u003Ccode>function SubmitButton() {\n  const { pending } = useFormStatus();\n  return &lt;button disabled={pending}&gt;{pending ? 'Saving...' : 'Submit'}&lt;\u002Fbutton&gt;;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Impact\u003C\u002Fh2>\u003Cp>Actions reduce boilerplate by 60% compared to manual loading\u002Ferror state management. Optimistic updates make UI feel instant.\u003C\u002Fp>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: How is useOptimistic different from just setting state optimistically?\u003C\u002Fstrong> useOptimistic automatically rolls back if the async action fails.\u003Cbr>\u003Cstrong>Q: Can Actions work with Server Actions (Next.js)?\u003C\u002Fstrong> Yes – same API works on client and server.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>React 19 Actions make form handling and mutations declarative. Adopt now – they're stable.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Freact19-actions.jpg",[17,91,92,93],"Actions","Forms","Optimistic UI","Maria Gonzalez","2025-04-15",[],{"id":98,"slug":99,"title":100,"subtitle":101,"shortDescription":102,"description":103,"featureImage":104,"category":105,"tags":106,"author":110,"publishedDate":111,"featured":37,"relatedPosts":112,"tech":22},207,"useref-mastery-dom-refs-instance-variables","useRef Mastery: DOM Refs, Instance Variables, and forwardRef","When and how to use refs – from basic DOM access to advanced imperative handles","Complete guide to useRef and refs in React – accessing DOM elements, storing mutable values without re-renders, forwarding refs, and building imperative component APIs.","\u003Ch2>Two Main Uses of useRef\u003C\u002Fh2>\u003Cp>1. \u003Cstrong>DOM refs:\u003C\u002Fstrong> Directly access HTML elements. 2. \u003Cstrong>Instance variables:\u003C\u002Fstrong> Store mutable values that persist across renders without causing re-renders.\u003C\u002Fp>\u003Ch2>DOM Ref Example\u003C\u002Fh2>\u003Cpre>\u003Ccode>function InputFocus() {\n  const inputRef = useRef(null);\n\n  useEffect(() => {\n    inputRef.current.focus();\n  }, []);\n\n  return &lt;input ref={inputRef} \u002F&gt;;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Instance Variable (no re-render)\u003C\u002Fh2>\u003Cpre>\u003Ccode>function Timer() {\n  const intervalRef = useRef(null);\n\n  const startTimer = () => {\n    intervalRef.current = setInterval(() => {}, 1000);\n  };\n\n  const stopTimer = () => {\n    clearInterval(intervalRef.current);\n  };\n\n  return &lt;button onClick={stopTimer}&gt;Stop&lt;\u002Fbutton&gt;;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>forwardRef + useImperativeHandle\u003C\u002Fh2>\u003Cpre>\u003Ccode>const FancyInput = forwardRef((props, ref) => {\n  const inputRef = useRef();\n\n  useImperativeHandle(ref, () => ({\n    focus: () => inputRef.current.focus(),\n    scrollToTop: () => inputRef.current.scrollTop = 0\n  }));\n\n  return &lt;input ref={inputRef} \u002F&gt;;\n});\n\nfunction Parent() {\n  const ref = useRef();\n  return &lt;&gt;&lt;FancyInput ref={ref} \u002F&gt;&lt;button onClick={() => ref.current.focus()}&gt;Focus&lt;\u002Fbutton&gt;&lt;\u002F&gt;;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Tips\u003C\u002Fh2>\u003Cul>\u003Cli>Reading\u002Fwriting refs doesn't trigger re-renders – use for performance-critical mutable data\u003C\u002Fli>\u003Cli>Avoid setting refs during render – use effect or callbacks\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Using refs for state that should trigger UI updates\u003C\u002Fli>\u003Cli>Expecting ref changes to cause re-renders\u003C\u002Fli>\u003Cli>Not using forwardRef when passing ref to custom component\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: Difference between useRef and createRef?\u003C\u002Fstrong> useRef is for functional components (persists across renders). createRef is for class components.\u003Cbr>\u003Cstrong>Q: Can you use ref on a custom component?\u003C\u002Fstrong> Only if that component uses forwardRef.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>useRef is essential for imperative DOM operations and mutable storage. Master forwardRef and useImperativeHandle for reusable component APIs.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Fuseref-mastery.jpg","React Hooks",[107,108,109,105],"useRef","forwardRef","DOM","Priya Sharma","2025-04-02",[],{"id":114,"slug":115,"title":116,"subtitle":117,"shortDescription":118,"description":119,"featureImage":120,"category":31,"tags":121,"author":124,"publishedDate":125,"featured":37,"relatedPosts":126,"tech":22},208,"react-context-usereducer-scalable-state","React Context + useReducer: Scalable State Without Redux","Build a lightweight Redux-like store using only built-in React APIs","Learn to combine React Context with useReducer to create a scalable state management solution for small-to-medium apps – no external libraries needed. Includes TypeScript, performance optimizations, and testing.","\u003Ch2>Why Context + useReducer?\u003C\u002Fh2>\u003Cp>useReducer manages complex state logic. Context shares that state across the component tree. Together they replace Redux for many apps – without the boilerplate.\u003C\u002Fp>\u003Ch2>Implementation\u003C\u002Fh2>\u003Cpre>\u003Ccode>\u002F\u002F store\u002FtodoReducer.js\nexport const initialState = { todos: [], filter: 'all' };\n\nexport function todoReducer(state, action) {\n  switch (action.type) {\n    case 'ADD_TODO': return { ...state, todos: [...state.todos, action.payload] };\n    case 'TOGGLE_TODO': return { ...state, todos: state.todos.map(t => t.id === action.id ? { ...t, done: !t.done } : t) };\n    default: return state;\n  }\n}\n\n\u002F\u002F context\u002FTodoContext.jsx\nconst TodoContext = createContext();\n\nexport function TodoProvider({ children }) {\n  const [state, dispatch] = useReducer(todoReducer, initialState);\n  return &lt;TodoContext.Provider value={{ state, dispatch }}&gt;{children}&lt;\u002FTodoContext.Provider&gt;;\n}\n\nexport function useTodo() {\n  const context = useContext(TodoContext);\n  if (!context) throw new Error('useTodo must be used within TodoProvider');\n  return context;\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Usage in Components\u003C\u002Fh2>\u003Cpre>\u003Ccode>function AddTodo() {\n  const { dispatch } = useTodo();\n  const [text, setText] = useState('');\n  return (\n    &lt;form onSubmit={(e) => { e.preventDefault(); dispatch({ type: 'ADD_TODO', payload: { id: Date.now(), text, done: false } }); setText(''); }}&gt;\n      &lt;input value={text} onChange={e => setText(e.target.value)} \u002F&gt;\n    &lt;\u002Fform&gt;\n  );\n}\n\nfunction TodoList() {\n  const { state } = useTodo();\n  return state.todos.map(todo => &lt;div key={todo.id}&gt;{todo.text}&lt;\u002Fdiv&gt;);\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Optimization\u003C\u002Fh2>\u003Cp>The above pattern causes all consumers to re-render on any state change. Fix with selectors:\u003C\u002Fp>\u003Cpre>\u003Ccode>function useTodoSelector(selector) {\n  const { state } = useTodo();\n  return selector(state);\n}\n\n\u002F\u002F Then: const todos = useTodoSelector(state => state.todos);\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Common Mistakes\u003C\u002Fh2>\u003Cul>\u003Cli>Putting the provider too high (re-renders entire app)\u003C\u002Fli>\u003Cli>Not memoizing dispatch actions\u003C\u002Fli>\u003Cli>Mutating state directly in reducer\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: When should you switch from Context+Reducer to Redux?\u003C\u002Fstrong> When you have frequent updates (many state changes per second), deeply nested selectors, or need devtools time-travel debugging.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>For small-to-medium apps, Context + useReducer is simpler and uses zero dependencies. Add selectors for performance.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Fcontext-reducer.jpg",[122,123,31,12],"Context API","useReducer","Tom Wilkinson","2025-03-25",[],{"id":128,"slug":129,"title":130,"subtitle":131,"shortDescription":132,"description":133,"featureImage":134,"category":12,"tags":135,"author":139,"publishedDate":140,"featured":37,"relatedPosts":141,"tech":22},209,"react-error-boundaries-error-handling","React Error Boundaries: Catching and Handling Errors Gracefully","Prevent entire app crashes with error boundaries and fallback UIs","Learn how to use React Error Boundaries to catch JavaScript errors in components, display fallback UI, log errors, and recover gracefully. Includes patterns for async errors and error recovery.","\u003Ch2>What Are Error Boundaries?\u003C\u002Fh2>\u003Cp>Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log them, and display a fallback UI instead of crashing the whole app.\u003C\u002Fp>\u003Ch2>Creating an Error Boundary (Class Component)\u003C\u002Fh2>\u003Cpre>\u003Ccode>class ErrorBoundary extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = { hasError: false, error: null };\n  }\n\n  static getDerivedStateFromError(error) {\n    return { hasError: true, error };\n  }\n\n  componentDidCatch(error, errorInfo) {\n    console.error('Logged:', error, errorInfo);\n    \u002F\u002F Send to Sentry\u002FLogRocket\n  }\n\n  render() {\n    if (this.state.hasError) {\n      return this.props.fallback || &lt;div&gt;Something went wrong&lt;\u002Fdiv&gt;;\n    }\n    return this.props.children;\n  }\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Using with Hooks (react-error-boundary library)\u003C\u002Fh2>\u003Cpre>\u003Ccode>import { ErrorBoundary } from 'react-error-boundary';\n\nfunction fallbackRender({ error, resetErrorBoundary }) {\n  return (\n    &lt;div role=\"alert\"&gt;\n      &lt;p&gt;Something failed: {error.message}&lt;\u002Fp&gt;\n      &lt;button onClick={resetErrorBoundary}&gt;Try again&lt;\u002Fbutton&gt;\n    &lt;\u002Fdiv&gt;\n  );\n}\n\nfunction App() {\n  return (\n    &lt;ErrorBoundary fallbackRender={fallbackRender} onReset={() => window.location.reload()}&gt;\n      &lt;MyComponent \u002F&gt;\n    &lt;\u002FErrorBoundary>\n  );\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Async Error Handling\u003C\u002Fh2>\u003Cp>Error boundaries don't catch errors in event handlers or async code. Use try\u002Fcatch:\u003C\u002Fp>\u003Cpre>\u003Ccode>function handleSubmit() {\n  try {\n    await saveData();\n  } catch (error) {\n    setError(error); \u002F\u002F display error in component state\n  }\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Production Tips\u003C\u002Fh2>\u003Cul>\u003Cli>Place boundaries at feature boundaries (e.g., each widget or route)\u003C\u002Fli>\u003Cli>Provide specific fallbacks per feature\u003C\u002Fli>\u003Cli>Log errors to monitoring service\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: Why are error boundaries class components?\u003C\u002Fstrong> Hooks have no equivalent for getDerivedStateFromError or componentDidCatch. The react-error-boundary library provides a hook-friendly wrapper.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>Error boundaries are essential for production React apps. Wrap each major UI section to prevent cascading failures.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Ferror-boundaries.jpg",[136,137,12,138],"Error Handling","Error Boundaries","Debugging","Nina Patel","2025-04-07",[],{"id":143,"slug":144,"title":145,"subtitle":146,"shortDescription":147,"description":148,"featureImage":149,"category":17,"tags":150,"author":154,"publishedDate":155,"featured":20,"relatedPosts":156,"tech":22},210,"react-compiler-forget-automatic-memoization","React Compiler (React Forget): Automatic Memoization Explained","Stop writing useMemo, useCallback, and React.memo – the compiler does it for you","Deep dive into React Compiler (formerly Forget) – how it automatically memoizes components, eliminates manual optimization, and improves performance. Includes adoption strategies and benchmarks.","\u003Ch2>What is React Compiler?\u003C\u002Fh2>\u003Cp>React Compiler is a build-time tool that automatically memoizes components – meaning you no longer need \u003Ccode>useMemo\u003C\u002Fcode>, \u003Ccode>useCallback\u003C\u002Fcode>, or \u003Ccode>React.memo\u003C\u002Fcode>. It analyzes your code and inserts memoization where beneficial.\u003C\u002Fp>\u003Ch2>How It Works\u003C\u002Fh2>\u003Cp>The compiler performs a static analysis of your component's dependencies (props, state, context). It determines which values can change and which remain stable, then automatically wraps components and hooks with memoization primitives.\u003C\u002Fp>\u003Ch2>Before (Manual)\u003C\u002Fh2>\u003Cpre>\u003Ccode>const ExpensiveList = React.memo(({ items, onItemClick }) => {\n  const sorted = useMemo(() => items.sort(), [items]);\n  const handleClick = useCallback((id) => onItemClick(id), [onItemClick]);\n  return &lt;ul&gt;{sorted.map(item => &lt;li key={item.id} onClick={() => handleClick(item.id)}&gt;{item.name}&lt;\u002Fli&gt;)}&lt;\u002Ful&gt;;\n});\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>After (Compiler)\u003C\u002Fh2>\u003Cpre>\u003Ccode>function ExpensiveList({ items, onItemClick }) {\n  const sorted = items.sort();\n  const handleClick = (id) => onItemClick(id);\n  return &lt;ul&gt;{sorted.map(item => &lt;li key={item.id} onClick={() => handleClick(item.id)}&gt;{item.name}&lt;\u002Fli&gt;)}&lt;\u002Ful&gt;;\n}\n\u002F\u002F Compiler adds memoization automatically\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch2>Performance Impact\u003C\u002Fh2>\u003Cp>Early benchmarks show 30-50% reduction in render time for complex apps. Code becomes simpler and less error-prone. No more incorrect dependency arrays or missing memoization.\u003C\u002Fp>\u003Ch2>Adoption Strategy\u003C\u002Fh2>\u003Col>\u003Cli>Enable compiler on a per-component basis with \u003Ccode>'use memo'\u003C\u002Fcode> directive\u003C\u002Fli>\u003Cli>Run codemod to remove existing manual memoization\u003C\u002Fli>\u003Cli>Test thoroughly – compiler respects existing memoization (won't break)\u003C\u002Fli>\u003C\u002Fol>\u003Ch2>Limitations\u003C\u002Fh2>\u003Cul>\u003Cli>Still experimental (as of React 19 beta)\u003C\u002Fli>\u003Cli>Doesn't work with dynamic imports or eval\u003C\u002Fli>\u003Cli>May increase bundle size slightly (but reduces runtime work)\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Interview Q&A\u003C\u002Fh2>\u003Cp>\u003Cstrong>Q: Will React Compiler replace useMemo\u002FuseCallback?\u003C\u002Fstrong> Eventually, yes – the goal is for manual hooks to become rare, only for advanced edge cases.\u003Cbr>\u003Cstrong>Q: Is React Compiler production-ready?\u003C\u002Fstrong> As of 2025 Q2, it's in beta. Major companies (Meta, Shopify) are testing internally.\u003C\u002Fp>\u003Ch2>Conclusion\u003C\u002Fh2>\u003Cp>React Compiler is the future of React performance. Start experimenting today – your code will become simpler and faster automatically.\u003C\u002Fp>","https:\u002F\u002Fcdn.example.com\u002Freact-compiler.jpg",[151,16,152,17,153],"React Compiler","Memoization","React Forget","Sophia Zhang","2025-04-14",[],1780160780762]