Summary — Episode 943: Modern React with Ricky Hanlon (React Core Dev)
Author/Hosts: Wes Bos & Scott Tolinski
Guest: Ricky Hanlon (React core developer)
Overview
This episode is a focused discussion with Ricky Hanlon about “modern React” features: transitions, Suspense, priorities/scheduling (the "concurrent" features), data fetching patterns, optimistic updates, and lessons from rolling out server components. The conversation emphasizes user-perceived performance, UX-first decisions, and how new React APIs coordinate work (network, rendering, and animations) rather than just making rendering faster.
Key Points & Main Takeaways
-
What a "transition" is:
- Think of a transition as a UI scheduling primitive — “like a transaction or a background thread.” It lets you mark lower-priority UI updates (navigation, large state updates, data loads) so they don’t block immediate user feedback.
- The big win is coordination (priorities), batching, and smoother UX (not mere faster rendering).
-
React’s concurrent features (fiber, transitions, Suspense) are scheduling tools:
- They allow deferring lower-priority work and coordinating async requests and animations.
- Goal: show immediate user feedback and then transition to the final result smoothly.
-
useTransition, useDeferredValue, and useOptimistic:
- useTransition: mark state updates as transitions (lower priority). Commonly used around navigation/data changes.
- useDeferredValue: defer updates at the "read" point so the UI can remain responsive.
- useOptimistic: show temporary (optimistic) UI immediately while background requests complete. Useful for likes, toggles, etc. (The isPending flag in useTransition is implemented with useOptimistic.)
-
Suspense behaviors and batching:
- React Suspense throttles fallbacks (commonly ~300ms) to avoid flicker and allow batching of updates. Showing a fallback that flickers quickly can feel slower than a slightly longer, consistent fallback.
- Throttling helps reduce DOM reads/layouts and groups animations, often improving perceived speed.
-
Data fetching and preloading:
- Best practice: prefetch/fetch as early as possible (e.g., on hover) and use Suspense-compatible patterns so navigation renders without causing unnecessary suspensions.
- Cache APIs are being developed but cache invalidation and a generic data API are hard problems.
-
Server Components and rollout lessons:
- Server Components were rolled out through canary/build-in-public processes; the rollout taught the team about messaging and community expectations.
- Next.js did early implementation and feedback was important; this does not mean Next "controls" React — React core aims to make features available broadly.
-
Future directions:
- Exploring a concurrent store API to sync state across threads/priorities (no firm details yet).
- Expect more of these capabilities to be exposed through framework/data-fetching/router/design-component layers so app developers get modern UX "for free."
Notable Quotes / Insights
- “You can think of a transition as... maybe a little bit like a transaction or like a background thread.”
- “That 300 milliseconds gives you 300 milliseconds to wait around and see if anybody else wants to update state… it’s actually sometimes faster to wait a little longer and animate everything together.”
- “The rendering itself is not the benefit — it’s the priorities and coordinating all of the async requests and coordinating all of the animations.”
- “If you have a suspense-enabled router or data fetching, you shouldn’t need to wrap your router.navigate in startTransition — that should be handled by the router.”
Topics Discussed
- Transitions (useTransition, scheduling, UX rationale)
- Suspense (fallback throttling, batching, animation coordination)
- useDeferredValue and useOptimistic
- Perceived performance and UX research (skeletons, metrics)
- Data fetching strategies (preload on hover, cached promises)
- View transitions / animations (document.startViewTransition mentioned)
- Server Components rollout & canary process, lessons learned
- Cache API & cache invalidation challenges
- Future APIs: concurrent store ideas (signals mention)
- Framework vs. core React responsibilities (Next.js, Hydrogen examples)
- Developer ergonomics and docs / communication challenges
- AI-generated code and how clearer declarative APIs help LLMs produce modern React
Action Items & Recommendations (for React developers)
- Use Suspense and a suspense-enabled router or data layer where possible to get proper scheduling and UX behavior.
- Use useTransition for lower-priority UI updates (navigation, heavy re-renders) and useOptimistic for instant feedback on user actions (likes, toggles).
- Use useDeferredValue when you need to defer a read so UI input remains smooth.
- Prefetch data early (e.g., on hover) to reduce suspense and perceived latency.
- Prefer letting frameworks / routers / design-system components handle transitions and scheduling so app code stays simple and declarative.
- Consider showing skeletons/placeholders to improve perceived performance — but rely on heuristics (like the throttling behavior) to avoid quick flickers.
- Measure perceived performance on real devices and users (not only local dev machines) — many issues only show up on real network/CPU profiles.
- Keep an eye on React Conf content (Ricky’s talk) and React core updates for practical examples and evolving patterns.
- When designing data/cache layers, be cautious: cache invalidation is hard—use established libraries or frameworks if possible.
Useful Links & Resources Mentioned
- Ricky: @rickyfm (BlueSky)
- React Conf (Ricky is presenting a deeper talk on these topics soon)
- Look into Suspense, useTransition, useDeferredValue, useOptimistic, useSyncExternalStore in React docs
If you want, I can:
- Extract specific code examples and show how to swap a naive approach for useTransition/useOptimistic/useDeferredValue.
- Summarize Ricky’s upcoming React Conf talk content (once available).
