react19-patterns
π―Skillfrom qingqishi/shiqingqi.com
Streamlines React 19 context and compiler patterns, providing optimized syntax for Context.Provider, use() hook, and automatic memoization.
Installation
npx skills add https://github.com/qingqishi/shiqingqi.com --skill react19-patternsSkill Details
React 19 patterns and React Compiler behavior with Context shorthand syntax and use() hook. Use when working with Context, useContext, use() hook, Provider components, optimization patterns like useMemo, useCallback, memo, memoization, or when the user mentions React 19, React Compiler, Context.Provider, or manual optimization.
Overview
# React 19 Patterns
Overview
This project uses React 19 with the React Compiler enabled. This changes how you should write React code, especially around Context and optimization.
React 19 Context Pattern
Use Shorthand Syntax
React 19 introduces shorthand syntax for Context providers.
β Correct (React 19):
```tsx
```
β Incorrect (Old pattern):
```tsx
```
Use `use()` Hook Instead of `useContext()`
React 19 introduces the use() hook for consuming context.
β Correct (React 19):
```tsx
import { use } from "react";
import { MyContext } from "./MyContext";
function MyComponent() {
const value = use(MyContext);
return
}
```
β Incorrect (Old pattern):
```tsx
import { useContext } from "react";
import { MyContext } from "./MyContext";
function MyComponent() {
const value = useContext(MyContext);
return
}
```
React Compiler Enabled
No Manual Memoization Needed
The React Compiler automatically optimizes components and handles memoization. Do not use manual memoization patterns.
β Correct (React Compiler handles it):
```tsx
function MyComponent({ items }) {
// React Compiler automatically memoizes this computation
const filteredItems = items.filter((item) => item.active);
// React Compiler automatically stabilizes this function reference
const handleClick = (id) => {
console.log(id);
};
return (
{filteredItems.map((item) => ( {item.name} ))}
);
}
```
β Incorrect (Manual memoization not needed):
```tsx
import { useMemo, useCallback, memo } from "react";
function MyComponent({ items }) {
// β Don't use useMemo - React Compiler handles this
const filteredItems = useMemo(
() => items.filter((item) => item.active),
[items],
);
// β Don't use useCallback - React Compiler handles this
const handleClick = useCallback((id) => {
console.log(id);
}, []);
return
}
// β Don't use memo() - React Compiler handles this
export default memo(MyComponent);
```
React 19 ViewTransition + Suspense Pattern
The Hydration Issue
When using to wrap content that includes Suspense boundaries, you may encounter hydration errors if some children are in Suspense while others are not.
Error Message:
```
A tree hydrated but some attributes of the server rendered HTML didn't match the client properties.
This won't be patched up. This can happen if a SSR-ed Client Component used...
Specifically: style={{view-transition-name:"_T_0_"}}
```
Root Cause:
- ViewTransition uses a "just-in-time" mechanism to apply
view-transition-namestyles only when transitions trigger - During SSR hydration, content reveals from non-Suspense children trigger ViewTransition activation
- This causes the client to apply styles during hydration that weren't in the server HTML
- React detects the mismatch and logs a hydration warning
The Solution: Consistent Suspense Boundaries
β Correct (All content in Suspense):
```tsx
```
β Incorrect (Mixed Suspense/non-Suspense):
```tsx
{children} {/ NOT in Suspense - causes hydration error! /}
```
Alternative (Suspense outside ViewTransition):
```tsx
{children}
```
Note: This alternative forces all content into the same loading state, which may not be desirable if Header and children should load independently.
Why This Fixes It
By wrapping all children in Suspense boundaries:
- Content reveals are coordinated through React's Suspense mechanism
- ViewTransition doesn't activate prematurely during hydration
- Server and client rendering remain consistent
- No hydration mismatch occurs
Key Rules
- Context Shorthand: Always use
instead of - use() Hook: Always use
use(Context)instead ofuseContext(Context) - No useMemo: React Compiler automatically memoizes expensive computations
- No useCallback: React Compiler automatically stabilizes function references
- No memo(): React Compiler automatically optimizes component re-renders
- Trust the Compiler: Let React Compiler handle optimization instead of manual patterns
- ViewTransition + Suspense: When using ViewTransition with Suspense, ensure all children are within Suspense boundaries to prevent hydration errors
When Manual Optimization Might Be Needed
In rare cases, you might still need manual optimization:
- External library integration that expects stable references
- Performance profiling shows a specific issue that React Compiler doesn't catch
Always profile first before adding manual optimizations. The React Compiler is very effective.
More from this repository5
Manages package dependencies using pnpm and corepack, automatically handling package manager versions and installations via the packageManager field.
Enables responsive and theme-aware styling using StyleX design tokens, breakpoints, and custom CSS prop for consistent component design.
Generates selective Zod schemas and TypeScript types for TMDB API endpoints, optimizing performance and enabling AI-powered structured outputs.
Streamlines API data retrieval with intelligent caching, error handling, and flexible request configurations for modern web applications.
Enables user-centric end-to-end testing with Playwright using semantic locators and best practices that focus on visible behavior.