LogotypeSlidebook

ReactJS

Title slide for a presentation: 'React.js in 2025 — A Pragmatic Deep Dive' against a dark, animated background with a stylized atom graphic.. Last fragment

React.js in 2025: A Pragmatic Deep Dive

Take a quiet beat as the ambient glow and atom lines settle in. Then read the title cleanly: “React.js in 2025 — A Pragmatic Deep Dive.” Emphasize the word pragmatic—this session is about clarity over hype. Set expectations: this is a 20-part journey from fundamentals to today’s realities—server components maturity, concurrent patterns that actually help, the bundler/runtime landscape, state management in a multi-runtime world, and practical architecture choices. Point to the subtle progress bar and say we’re at 0 out of 20—this is just the starting frame. Mention the minimalist aesthetic is intentional: we will focus on decisions, tradeoffs, and signals over noise. Briefly introduce yourself and the event as shown in the subtitle. Then note the timestamp to situate the talk in time—it matters because React’s ecosystem moves fast. Transition: as the title fades in and the subtitle slides up, invite the audience to question assumptions as we move from shiny features to battle-tested practice.

Read more about slide →
A slide titled 'Why React Still Matters' with four bullet points highlighting its strengths: stable core, battle-tested ecosystem, modern performance, and community strength. Each point is accompanied by a relevant icon.. Last fragment

Why React Still Matters: A Deep Dive into its Relevance

Open by acknowledging React’s age and impact: it’s not hype, it’s staying power. Then move through four proof points. 1. Stability: React’s core is steady with predictable, incremental upgrades. Teams can adopt new features without rewrites, which keeps products shipping. 2. Ecosystem: From frameworks like Next.js and Remix to robust UI kits, devtools, and build tooling, the ecosystem is mature and battle‑tested for real-world needs. 3. Performance: React Server Components reduce client‑side JavaScript, enable streaming, and pair with concurrent rendering to improve time‑to‑interactive and overall UX. 4. Community and longevity: Hiring is easier with a massive talent pool, documentation is abundant, and long-term stewardship by Meta and the community lowers project risk. Close: React still matters because it balances stability with innovation, performance with DX, and today’s needs with long-term viability.

Read more about slide →
A slide displaying the formula UI = f(state) with 'state' highlighted in teal. Below, a diagram illustrates the flow: Event → State Update → Render.. Last fragment

UI as a Function of State in React

<div> <ol> <li>Start by pointing to the big formula: “UI equals a function of state.” Emphasize that in React we describe what the UI should look like for a given state.</li> <li>Advance to reveal and highlight the word “state.” Explain that the function is pure conceptually: same state, same UI output.</li> <li>Introduce the three-step flow below: Event, State Update, Render.</li> <li>When the first arrow appears, say: “An event happens — a click, input, or network response.”</li> <li>When the second arrow appears, continue: “That event updates state, and React re-renders the UI from that state.”</li> <li>Wrap up: “Think declaratively. Don’t manipulate the DOM; define UI as f(state), and let React handle the rest.”</li> </ol> </div>

Read more about slide →
Slide shows JSX code transforming into compiled JavaScript, highlighting tags, props, and children with color-coded syntax and animations.. Last fragment

JSX Transformation: From Syntax Sugar to JavaScript Runtime

First, set the frame: JSX is not a runtime feature; it is syntax sugar that tooling compiles away. Reveal both columns. Point out the left is what we write, the right is what actually executes after the build. Step 1 highlight tags: show how the JSX h1 maps to a string "h1" passed to the JSX runtime function. For components, the tag becomes a reference to the component function. Step 2 highlight props: the JSX attributes become keys on a plain object, like className: "text-blue-600" and name: "React". Step 3 highlight children: the inner text and expressions become an ordered children array, preserving strings, variables, and punctuation. Emphasize that we rarely write _jsx or _jsxs manually; Babel or TypeScript with the React JSX transform does this. In older setups, you might see React.createElement instead, but the idea is the same. Close by reinforcing: Browsers never see JSX. Our tooling turns it into function calls and objects before it runs.

Read more about slide →
A slide about React components illustrating props, state, and pure render with a code example and key concept explanations.. Last fragment

React Components: Props, State, and Purity

Title: Components: Props, State, and Purity. Call out the Pure render badge: it signals our goal for predictable UIs. First, define a function component: it’s just a function that takes props and returns JSX — props in, UI out. Second, contrast props vs state. Props are external and immutable from the component’s perspective. State is internal data. Updating state with setState triggers a re-render. Third, purity: during render, avoid side effects. Given the same props and state, the component should produce the same output. Do effects in event handlers or useEffect, not inside render. Walk the code: Greeting receives a name and returns JSX — it’s pure. Demo shows the one-liner useState. Clicking the button updates count, which re-renders and updates the label. Wrap up: Design components as pure render functions, use props for inputs, use state for local, evolving data.

Read more about slide →
Three boxes illustrate the React render workflow: Render, Diff, and Commit, connected by a line. The Commit box is highlighted.. Last fragment

React's Render Workflow: A Step-by-Step Breakdown

We’ll walk through React’s high-level render cycle from left to right. First, Render: React builds the new virtual tree and splits work into fibers—small units that can be scheduled and paused. Second, Diff: React compares the new tree to the previous one to calculate the minimal set of changes needed. Finally, Commit: Only here do we touch the real DOM, apply mutations, and run layout and effect lifecycles. Notice the small Fiber tag under Render—this is the cooperative scheduling layer that makes rendering interruptible. Key takeaway: Render and Diff are computational planning; Commit is the execution phase that updates the screen. Keep this mental model in mind when debugging performance or effect timing issues.

Read more about slide →
Slide illustrating the benefits of using stable keys in React lists. It shows a before and after comparison of a list rendered with array indices versus stable IDs, highlighting how stable keys prevent unnecessary re-renders when the list is reordered.. Last fragment

React Keys and Reconciliation: Optimizing Performance with Stable Identifiers

Open with the core idea: React reconciles by matching elements across renders, and keys are how we give each item a stable identity. Point to the first bullet: Stable keys. Explain that a key must uniquely and consistently identify the same conceptual item across renders. Advance to the second bullet and the right panel fade. Contrast index keys with stable ids. Using an array index ties identity to position, not to the item. Describe the before state: A, B, C keyed by indices. When order changes, React assumes different elements because positions changed. As the after state fades in, highlight stable ids: B, A, C keep their identity via id=7, id=42, id=99. React moves nodes instead of remounting. Advance to the third bullet: Reorder costs. With index keys, reorders can cause unnecessary unmounts and remounts, losing local state and triggering effects. Close with the tiny tip: Deterministic identity prevents remounts. Always prefer a real, stable key derived from data, not from array position.

Read more about slide →
Slide displaying six cards, each representing a core React Hook (useState, useEffect, useMemo, useCallback, useRef, Rule of Hooks). Each card provides a concise title and a brief tip for best usage.. Last fragment

Core React Hooks: A Quick Guide

1. Set the frame: this is a fast tour of the core hooks we reach for in daily React—what each is for, and the one-sentence guidance. 2. useState: Emphasize keeping state minimal. Encourage deriving values (like counts, filters, computed flags) instead of storing duplicates that drift out of sync. 3. useEffect: Explain it as the bridge to the outside world—subscriptions, timers, DOM, network. Stress small, focused effects with full dependency lists, and preferring event handlers or derived rendering when possible. 4. useMemo: Position it as a cache for expensive computations. Only introduce when you can feel or measure the cost, or when a stable value prevents churn downstream. 5. useCallback: Clarify it stabilizes function identity to satisfy dependency arrays and memoized children. On its own it does not make code faster—value comes from avoiding needless re-renders in children. 6. useRef: Use it as a mutable box for values that don’t trigger re-renders (timestamps, previous values) and for DOM node references. Great for imperative escapes and integrating third‑party widgets. 7. Close with the Rule of Hooks: call hooks at the top level, same order every render—never inside loops or conditionals. That’s how React preserves state correctly. 8. Invite questions on trade-offs or real cases where these rules simplify a component.

Read more about slide →
Slide illustrating common useEffect pitfalls and best practices in React. The left side highlights pitfalls in red, while the right side shows correct usage in green with a code example demonstrating proper dependencies and cleanup.. Last fragment

useEffect Pitfalls and Best Practices in React

Open by framing useEffect as powerful but easy to misuse. Set the goal: avoid pitfalls and adopt a reliable pattern. Point to the left: three common mistakes. Read each briefly: missing dependencies causing stale closures, heavy synchronous work inside effects causing jank, and fetching in effects leading to waterfalls and duplicate requests. Let the red list shake to emphasize that these are problematic habits developers fall into. Shift attention to the right code snippet. Highlight the two essentials: a cleanup function and a precise dependency array. Explain that effects should be deterministic and reversible. Reveal the green “Better Pattern” card. Walk through each guideline: derive UI from state/props first; move data fetching to loaders, Suspense, or a data library; reserve effects for subscriptions, timers, and imperative bridges to non-React systems. Conclude by connecting the code back to the pattern: this effect manages a timer (an external system) with a cleanup and stable dependency. That’s the model to follow.

Read more about slide →
Slide illustrating the difference between blocking and concurrent rendering in React.  The left side depicts a blocked UI with lagging interactions, while the right side shows a responsive UI with background updates indicated by a spinner.. Last fragment

Concurrent Rendering in React: Keeping UI Responsive

Set the scene: React now supports concurrent rendering, which means it can prepare updates without blocking the main thread. The key idea is that not all updates are equal. Define urgent versus non‑urgent. Urgent updates are the ones users must see immediately: text echo, selection, pointer movement. Non‑urgent updates are heavier work like lists, filters, and charts that can finish a moment later. Point to the left box: Before, a heavy update would block rendering. Typing felt laggy, the UI waited to update, and even clicks felt stuck because everything competed on the same thread. Reveal the right box: With concurrent rendering, we keep urgent interactions responsive and let non-urgent rendering be interruptible and scheduled when there’s time. The spinner indicates work in progress while the input remains snappy. Show the code snippet: useTransition gives us isPending and startTransition. Do the urgent update immediately, then wrap the heavy state update in startTransition so React treats it as non‑urgent. isPending is what drives small affordances like spinners or disabling secondary controls. Close: The mental model is simple—mark what can wait. React will schedule it without freezing the UI.

Read more about slide →
Diagram illustrating a React component tree with a Suspense boundary around a 'Chart' component. A fallback label is displayed while the chart data loads, and then transitions to the rendered chart once the data is available.. Last fragment

Suspense Boundaries and Fallbacks in React

Introduce Suspense as a way to draw a boundary around slow parts of the tree, so we can show a predictable fallback while data loads. Point to Header and Content as normal nodes; they render immediately. Advance: the dashed outline appears around Chart — this is the Suspense boundary. Emphasize it only wraps the slow branch. Advance: show the small “fallback” label. Explain this is what users see while Chart data is loading; the rest of the UI is unaffected. Advance: fallback gives way to the Chart content. Highlight that the loading state is localized and predictable. Conclude: Wrap only what may suspend; leave the rest outside to keep the app responsive.

Read more about slide →
Diagram illustrating React Server Components architecture. A server box labeled 'Server' shows 'Render RSC', 'Data fetching near the DB', and 'Sends HTML + payload'. A client box labeled 'Client' shows 'Hydrate boundaries', 'Add interactivity where needed', and 'client component boundary'. The server box has a tag 'no bundle'.. Last fragment

React Server Components (RSC): Benefits and Architecture

Start by defining RSC: components that render on the server and ship their output, not their JavaScript. Call out the first two bullets: no client JS for server-only parts, so you don’t pay hydration costs where you don’t need interactivity. Emphasize data proximity: fetching happens next to your database or APIs, reducing waterfalls and round trips. Next: smaller bundles and faster time-to-interactive because large server-only UI never gets bundled for the client. Point to the diagram: the Server box renders RSC. The arrow shows the stream flowing to the Client. On the Client side, hydration happens only at boundaries where you introduce client components for interactivity. Finally, highlight the “no bundle” tag in the server box—those parts don’t ship JS, which is the core win.

Read more about slide →
Slide comparing server-side and client-side data fetching in React. Code examples are shown for each approach, with comparisons for performance, caching, and UX. Visual cues highlight which method excels in each category.. Last fragment

Data Fetching: Server vs. Client in React

Title: introduce the split between server fetching in React Server Components/route handlers and client-side fetching with libraries. Point to the left column first. Explain that server fetching runs on the server, can stream HTML, benefits SEO, and leverages HTTP caching and ISR out of the box. Walk through the tiny RSC example. Move to the right column. Explain client fetching with SWR/React Query excels at per-user state, revalidation on focus, and optimistic updates. Walk through the short SWR example. Shift to the comparison row. Performance favors server for initial load and SEO; show the check on Server. Caching can live in both places: server for shared/public and ISR, client for per-user cache; highlight both checks. UX favors client for optimistic and live updates. Conclude with the bottom chips: when to use each. Server for SEO/static, shared data, edge/streaming. Client for interactive views, user-specific data, and optimistic UX.

Read more about slide →
Slide illustrating three approaches to state management in React: Local, Context, and External Store. Each approach is presented in a separate card highlighting its use case and trade-offs.  A footer below the External Store card lists Redux Toolkit, Zustand, and Jotai as examples.. Last fragment

State Management in React: Choosing the Right Approach

Open with the rule of thumb: start local, elevate with Context, and use an external store only when the scope becomes cross-cutting or caching gets complex. Point to the first card. Explain Local state: ideal for UI-specific, short-lived logic like form inputs and toggles. It’s simple and fast. The trade-off is sharing—prop drilling appears, and state can reset on unmount. Reveal the Context card. Describe Context as a way to share values across a subtree: theme, auth, and preferences. Emphasize that frequent updates can cause re-renders—suggest splitting providers, memoizing values, or using selectors in consumers. Reveal the External store card. Explain when to choose it: cross-page or cross-feature state, complex derivations, optimistic flows, and caching. Acknowledge added API surface and mental model, but call out the payoff: scalability and tooling. Name examples: Redux Toolkit, Zustand, Jotai. When the arrow draws, reinforce the escalation path. Encourage the audience to keep state as close as possible to where it’s used, and only move right when pain points justify it.

Read more about slide →
A slide titled 'Performance Patterns That Matter' with a speedometer icon. It lists React performance tips like memoization, virtualization, selective re-renders, splitting components, and measuring performance.  A code snippet demonstrates memoization and virtualization with React.memo, useCallback, and react-window.  A tip suggests prioritizing coarse-grained optimizations.. Last fragment

React Performance Optimization Patterns

Open by framing the goal: make the UI feel instant by avoiding unnecessary work. Point to the speedometer icon and title. First, memoize wisely. Explain React.memo for pure subtrees and that useMemo/useCallback are tools, not defaults. Show the sky highlight on the memo line. Second, virtualize long lists. Emphasize rendering only what the user can see. Call out the react-window import highlight in emerald. Third, selective re-renders. Describe colocating state, splitting contexts, and stabilizing props to reduce churn. Fourth, split big components. Encourage lazy loading with Suspense and deferring heavy children to shrink the initial work. Finally, measure first. Point to the small profiler badge and recommend React Profiler and the browser Performance tab to validate wins. Close with the tip: favor coarse-grained wins like virtualization and splitting before micro-optimizing hooks.

Read more about slide →
Slide depicting a React code snippet for a controlled input, a mock form UI, and bullet points explaining keys in lists, controlled vs uncontrolled inputs, and scaling form management.. Last fragment

React Forms and Lists: Keys, Controlled Inputs, and Scaling

Title: Introduce the three pillars on this slide — lists, forms, and controlled inputs — and how they connect in real apps. Lists and keys: Explain that keys are about identity. Use stable IDs; avoid array indexes when order can change. Emphasize that stable keys preserve DOM state — focus, caret position, and component-local state — which avoids jank during reordering or filtering. Controlled vs uncontrolled: Define controlled inputs as using React state as the single source of truth. Benefits: validation, masks, formatting, cross-field rules. Trade-off: more renders and potential performance costs in large forms. Uncontrolled: Describe relying on the DOM state via refs and form submission. Benefits: fewer renders, good for big or static forms. Trade-off: more complex inter-field logic and synchronous validation. Code: Walk through the snippet — value and onChange wire the input to React state. Mention debouncing or onBlur validation as scalability tactics. Form libraries: When complexity grows (nested fields, arrays, async rules), reach for a form library plus schema validation. Highlight watching performance: lazy registration, field arrays, and avoiding unnecessary re-renders. Close: Point back to keys ensuring stability as your UI mutates, and choosing the right control model for each form or field. Invite questions about migration paths or hybrid approaches.

Read more about slide →
Slide on web accessibility best practices, showing a checklist of key considerations like semantic HTML, labeling, focus management, keyboard navigation, and ARIA attributes, along with a code example demonstrating proper label association and focus trap activation.. Last fragment

Accessibility by Design in Web Development

Start by framing the mindset: accessibility is a design constraint and a quality bar, not a bolt-on. Explain semantic first: using native elements gives you roles, names, and keyboard behavior for free. Move to labels: every input needs a programmatic name; labels improve hit targets and screen reader output. Cover focus management: set initial focus when opening components, trap focus inside modals, and restore focus to the trigger on close. Emphasize full keyboard navigation: Tab and Shift+Tab to move, Enter/Space to activate, and Arrow keys within composite widgets like menus. Stress “ARIA only when needed”: prefer native elements; when you must build custom, provide correct role and aria state that mirrors UI state. Mention useId: stable IDs prevent SSR/CSR mismatches for htmlFor and aria attributes in React. Close with color contrast: meet at least AA 4.5:1 and do not rely solely on color to convey meaning. Point to the code strip: show useId for label/input association and a focus trap activation when a dialog opens. Invite the audience to think about adding these checks to PR templates or component definitions so they become habits.

Read more about slide →
Slide comparing CSS Modules, Utility-first CSS, and CSS-in-JS styling approaches in React.. Last fragment

React Styling Strategies: CSS Modules, Utility-First, and CSS-in-JS

Title: introduce three mainstream styling strategies: CSS Modules, Utility-first with Tailwind, and CSS-in-JS. Explain that we will compare pros/cons quickly and focus on when to pick each, plus bundle impact and tree-shaking. CSS Modules: emphasize local scoping, zero runtime. Mention great tree-shaking because unused classes get dropped by the build. Call out harder global theming and token sharing. Tailwind: highlight speed and consistent tokens. Stress that purge/content scanning eliminates unused utilities for small CSS. Note drawbacks: verbose class lists and need for plugins for custom patterns. CSS-in-JS: highlight dynamic, prop-driven styles and robust theming. Caution about runtime overhead and bundle growth unless using compile-time extraction or libraries with zero-runtime modes. Decision guidance: Modules for minimal JS and conventional CSS; Tailwind for fast, consistent delivery; CSS-in-JS for dynamic themes and per-prop styling needs.

Read more about slide →
A slide about React testing strategies showing a pyramid graphic illustrating unit, component, and integration tests.  A code snippet exemplifies a test using React Testing Library.. Last fragment

Effective React Testing Strategies for Developers

Open with the theme: we want high confidence without slowing developers down. Walk through the four bullets: 1. Recommend React Testing Library for DOM behavior—assert what users see, not implementation details. 2. Use Jest or Vitest for units to keep feedback loops fast and isolated. 3. Prefer component tests over snapshots; snapshots often lock in noise and discourage refactors. 4. Favor integration tests across boundaries; reserve E2E for a few critical flows. Add lightweight React Profiler-based tests to catch performance regressions. Point to the pyramid: unit at the top, component in the middle, integration as the base. As the bars fill, explain that confidence grows as you compose layers, but keep most tests in the middle two layers. Finally, reveal the RTL snippet and read it quickly: render, interact with userEvent, assert visible outcome. Emphasize that this is the standard shape—short, behavior-driven, fast.

Read more about slide →
Slide showcasing modern web development tools and delivery techniques for faster user experiences. It features code examples using React's lazy() and Suspense, a flow diagram illustrating SSR and hydration, and bullet points highlighting key concepts like Vite, Next.js, and code splitting.. Last fragment

Modern Tooling and Delivery for Fast Web Experiences

Title: Frame the slide as how we ship fast and light with modern tooling. Start with Vite and Next.js: fast HMR, smart caching, and solid build pipelines for TS/CSS/assets. Explain code splitting: both route-level and component-level via dynamic import. Point to the one-liner: const Chart = lazy(() => import('./Chart')) — lazy plus Suspense defers work until needed. Call out Suspense fallback behavior and how it enables smooth loading states. Walk the flow: Route → SSR/Streaming → Hydration. Emphasize streaming HTML and progressive hydration. Clarify delivery targets: Node SSR or Edge runtime; choose Edge when latency and proximity matter. Close with bundling strategy: tree-shaking, vendor chunk splits, and prefetching critical paths to keep TTFB and TTI tight.

Read more about slide →
Slide displaying React best practices, contrasting Don'ts (prop drilling, derived state, overusing useEffect, stale closures) with Do's (lifting state, deriving values on render, using TanStack Query/SWR, stabilizing handlers).. Last fragment

React Best Practices: Do's and Don'ts

We’ll close with a quick contrast between anti-patterns and what to do instead. First, the Don’ts: call out prop drilling through deep trees, derived state stored from props, overusing useEffect for data or DOM sync, and the stale closure problem in handlers and effects. Now I’ll dim those and bring in the Do list: lift state and use Context or Providers to share instead of drilling; derive values on render to avoid duplicating state; use TanStack Query or SWR for data fetching and keep effects minimal; and stabilize handlers with useCallback, refs, and functional updates to avoid stale closures. Migration notes: map class lifecycles to effects, replace legacy context with modern Context, switch createRef to useRef, and use functional updates instead of relying on outdated setState patterns. Resources link points to “You might not need an Effect” on react.dev. The example repo is Bulletproof React for structure and patterns. We’re at slide 20 of 20—thanks!

Read more about slide →

Want to try this presentation?

Try in Slidebook →