Intermediate concepts in React & Next.js, page 2

Zod: Validate Data, Infer Types
Zod acts as a bouncer for your data, validating it against a schema you define and inferring TypeScript types automatically. It's essential for validating API inputs or form submissions. The main footgun is forgetting to enable "strict": true in your tsconfig.
Handling File Uploads in React
Treat a file input like a remote control for the browser's file picker. React can't hold the file data directly in state, but it can grab a reference to the selected file and send it to a server using a FormData object.

Debouncing vs. Throttling in React
Debouncing waits for a pause in events before acting; throttling fires at a steady rate. Use debounce for search bars to avoid API calls on every keystroke, and throttle for scroll handlers to prevent lag.

React DevTools Profiler: Find Performance Bottlenecks
The React Profiler records how long components take to render, helping you find performance bottlenecks. Use it to diagnose slow interactions and see which components re-render too often.
List Virtualization: Render the Window, Not the World
Virtualization renders only the visible "window" of a long list, not the entire dataset. It's essential for performance in feeds or tables with thousands of rows.
Bundle Analysis: An X-Ray for Your App's Weight
Bundle analysis is an X-ray for your compiled JavaScript, showing which libraries contribute to your app's final size. Use it to diagnose slow loads by finding large or duplicated dependencies. The footgun: focus on gzipped size, not raw size.
Next.js SSG: Pre-render Pages for Maximum Speed
Next.js's Static Site Generation (SSG) pre-renders pages into static HTML at build time, serving them instantly from a CDN. It's ideal for content that rarely changes, like blog posts, ensuring top performance. The main pitfall is serving stale data.
Tree Shaking: Shipping Only the Code You Use
Tree shaking is a build step that eliminates unused code from your final bundle. Bundlers like webpack use it to shrink JavaScript files by removing functions you import but never call.
Redux Toolkit: `createSlice` Bundles Your Redux Logic
createSlice bundles a piece of state, its reducers, and action creators into one unit, killing Redux boilerplate. Use it to organize your store by feature. The footgun: its "mutating" syntax only works here due to Immer, not in plain Redux.

Jotai Derived Atoms: Computed State from Other Atoms
Think of a derived atom like a spreadsheet formula: its value is computed from other atoms. Use it for reactive values like a cart total from item prices. The footgun: the get in your read function is reactive, but the get in your write function.
user-event vs. fireEvent: Testing Real User Interactions
user-event tests how users actually interact with your UI, not just isolated DOM events. It simulates a full action sequence, like a click firing pointerdown, mousedown, and click. Use it to test component behavior from a user's perspective.

Jest Mocks: Spies for Your Functions
A Jest mock is a spy that watches a function, recording calls without running the original logic. This lets you isolate code under test, verify interactions like callbacks, and control return values. The footgun is assuming mocks run real logic—they don't.
Handling Asynchronous UI with Testing Library
Your test shouldn't race your UI. Use async helpers to wait for elements to appear, disappear, or change after an event. This is crucial for testing components that fetch data. The footgun is forgetting await on findBy or waitFor calls.

Snapshot Testing: Lock In Your UI's Rendered Output
Snapshot testing catches unintended UI changes by comparing a component's rendered output to a saved 'golden' version. Use it to ensure UIs don't break during refactors. The biggest footgun is blindly updating snapshots, which can approve bugs as correct.
Cypress for End-to-End Testing in Next.js
Cypress is a framework for end-to-end testing of Next.js applications. It's presented as a primary option in the official docs, alongside tools like Playwright and Vitest, for automating tests that simulate real user interactions in a browser.
Server Components: Fetch Data Directly
Server Components let you fetch data directly using async/await, simplifying code by removing client-side useEffect hooks. Use this for initial page loads in Next.js to improve SEO and performance. The footgun: don't use client-side hooks or browser APIs.
Route Handlers: Your Next.js App's API Endpoints
Route Handlers are lightweight API endpoints built into your Next.js app. Use them to serve JSON or handle form posts. The footgun is confusing them with Server Components; Route Handlers return data, not rendered UI.
Next.js Loading UI: Instant Shells, Streamed Content
Next.js's loading.js shows an instant UI shell while streaming in server-rendered content. Use it for data-heavy pages to improve perceived performance. The footgun: a loading UI only wraps its own route segment and children, not parent layouts.
error.js: Graceful Error Boundaries in Next.js
The error.js file acts as a UI safety net, catching runtime errors in a Next.js route segment to prevent a full app crash. Use it to display a custom error message and a "try again" button.
Next.js Metadata API: Control Your Site's Preview
The Next.js Metadata API is a structured way to control your page's <head> for SEO and social sharing. It lets you define titles, descriptions, and Open Graph images for crawlers and link previews.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles