react-patterns
giuseppe-trisciuoglio/developer-kit
React 19 patterns for Server Components, Server Actions, optimistic UI, and concurrent rendering with Next.js App Router.
What is react-patterns?
Comprehensive reference for React 19 development patterns including Server Components, Server Actions, useOptimistic, useActionState, useTransition, and concurrent features. Use when building React 19 applications with Next.js App Router, implementing optimistic UI, or optimizing concurrent rendering.
- Generates executable code patterns for Server Components, Client Components, and Server Actions
- Provides hooks reference for useState, useReducer, useEffect, useContext, useRef, useMemo, useCallback, useTransition, useDeferredValue, useOptimistic, useFormStatus, and useActionState
- Includes TypeScript integration patterns for type-safe props and form data
- Demonstrates Suspense boundaries for async data fetching and error handling
- Covers performance optimization with React Compiler or manual memoization
- Validates Server Action security with Zod schema validation
How to install react-patterns
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill react-patternsHow to use react-patterns
- 1.Identify whether you need a Server Component (default, async) or Client Component ('use client' directive)
- 2.Select appropriate hooks from the Quick Reference table based on your use case
- 3.Define TypeScript interfaces for all component props and form data
- 4.Wrap async data-fetching components in Suspense boundaries with fallback UI
- 5.Implement validation using Zod schemas for Server Actions before database operations
- 6.Test Server Actions with invalid and valid inputs to verify rejection and success behavior
- 7.Apply React Compiler or manual memoization (useMemo, useCallback, memo) for expensive renders
Use cases
- Building optimistic UI with instant feedback using useOptimistic and form submissions
- Implementing Server Actions with form validation and error handling
- Creating non-urgent updates on large lists with useTransition for better responsiveness
- Migrating from class components to functional components with hooks
- Setting up Suspense boundaries for async Server Components
- React 19 developers building with Next.js App Router
- Full-stack engineers implementing Server Actions and optimistic UI
- Teams migrating from older React patterns to concurrent features
- Developers optimizing performance in data-heavy applications
react-patterns FAQ
Start with Server Component (default, no directive needed). Add 'use client' only when you need hooks, browser APIs, or event handlers. Server Components are better for data fetching and security-sensitive operations.
Use useOptimistic hook to update UI immediately while the Server Action runs in the background. The hook accepts initial state and an updater function that applies the optimistic change, then reverts if the action fails.
useTransition marks state updates as non-urgent and provides isPending status. useDeferredValue defers rendering of a value to keep the UI responsive. Use useTransition for user actions; use useDeferredValue for derived state like search results.
Define a Zod schema to validate form data, use schema.safeParse() to check inputs, and return field errors if validation fails. Always validate on the server side before database operations.
No. React Compiler automatically memoizes components and callbacks, eliminating the need for manual memo(), useMemo, and useCallback. Only use them if you're not using React Compiler.
Full instructions (SKILL.md)
Source of truth, from giuseppe-trisciuoglio/developer-kit.
name: react-patterns description: Provides comprehensive React 19 patterns for Server Components, Server Actions, useOptimistic, useActionState, useTransition, concurrent features, Suspense boundaries, and TypeScript integration. Generates executable code patterns, validates security for public endpoints, and optimizes performance with React Compiler or manual memoization. Proactively use when building React 19 applications with Next.js App Router, implementing optimistic UI, or optimizing concurrent rendering. allowed-tools: Read, Write, Edit, Bash, Grep, Glob
React 19 Development Patterns
Overview
React 19 patterns for Next.js App Router, Server Actions, optimistic UI, and concurrent features. See Quick Reference for API summary and Examples for copy-paste patterns.
When to Use
- Building React 19 applications with Next.js App Router
- Implementing optimistic UI with
useOptimisticoruseTransition - Creating Server Actions with form validation
- Migrating from class components to hooks
- Optimizing concurrent rendering with React Compiler
- Managing complex state with
useReduceror custom hooks - Wrapping async operations in Suspense boundaries
Quick Reference
| Pattern | Hook / API | Use Case |
|---|---|---|
| Local state | useState | Simple component state |
| Complex state | useReducer | Multi-action state machines |
| Side effects | useEffect | Subscriptions, data fetching |
| Shared state | useContext / createContext | Cross-component data |
| DOM access | useRef | Focus, measurements, timers |
| Performance | useMemo / useCallback | Expensive computations |
| Non-urgent updates | useTransition | Search/filter on large lists |
| Defer expensive UI | useDeferredValue | Stale-while-updating |
| Read resources | use() (React 19) | Promises and context in render |
| Optimistic UI | useOptimistic (React 19) | Instant feedback on mutations |
| Form status | useFormStatus (React 19) | Pending state in child components |
| Form state | useActionState (React 19) | Server action results |
| Auto-memoization | React Compiler | Eliminates manual memo/callback |
Instructions
- Identify Component Type: Determine if Server Component or Client Component is needed
- Select Hooks: Use appropriate hooks for state management and side effects
- Type Props: Define TypeScript interfaces for all component props
- Handle Async: Wrap data-fetching components in Suspense boundaries
- Optimize: Use React Compiler or manual memoization for expensive renders
- Handle Errors: Add ErrorBoundary for graceful error handling
- Validate Server Actions: Define Zod/schema validation, then test:
- Submit invalid inputs → verify rejection
- Submit valid inputs → verify success
Examples
Server Component with Client Interaction
// Server Component (default) — async, fetches data
async function ProductPage({ id }: { id: string }) {
const product = await db.product.findUnique({ where: { id } });
return (
<div>
<h1>{product.name}</h1>
<AddToCartButton productId={product.id} />
</div>
);
}
// Client Component — handles interactivity
'use client';
function AddToCartButton({ productId }: { productId: string }) {
const [isPending, startTransition] = useTransition();
const handleAdd = () => {
startTransition(async () => {
await addToCart(productId);
});
};
return (
<button onClick={handleAdd} disabled={isPending}>
{isPending ? 'Adding...' : 'Add to Cart'}
</button>
);
}
useOptimistic for Instant Feedback
'use client';
import { useOptimistic } from 'react';
function TodoList({ todos, addTodo }: { todos: Todo[]; addTodo: (t: Todo) => Promise<void> }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo: Todo) => [...state, { ...newTodo, pending: true }]
);
const handleSubmit = async (formData: FormData) => {
const newTodo = { id: Date.now(), text: formData.get('text') as string };
addOptimisticTodo(newTodo); // Immediate UI update
await addTodo(newTodo); // Actual backend call
};
return (
<form action={handleSubmit}>
{optimisticTodos.map(todo => (
<div key={todo.id} style={{ opacity: todo.pending ? 0.5 : 1 }}>
{todo.text}
</div>
))}
<input type="text" name="text" />
<button type="submit">Add</button>
</form>
);
}
Server Action with Form
// app/actions.ts
'use server';
import { z } from 'zod';
import { revalidatePath } from 'next/cache';
const schema = z.object({
title: z.string().min(5),
content: z.string().min(10),
});
export async function createPost(prevState: any, formData: FormData) {
const parsed = schema.safeParse({
title: formData.get('title'),
content: formData.get('content'),
});
if (!parsed.success) {
return { errors: parsed.error.flatten().fieldErrors };
}
await db.post.create({ data: parsed.data });
revalidatePath('/posts');
return { success: true };
}
// app/blog/new/page.tsx
'use client';
import { useActionState } from 'react';
import { createPost } from '../actions';
export default function NewPostPage() {
const [state, formAction, pending] = useActionState(createPost, {});
return (
<form action={formAction}>
<input name="title" placeholder="Title" />
{state.errors?.title && <span>{state.errors.title[0]}</span>}
<textarea name="content" placeholder="Content" />
<button type="submit" disabled={pending}>
{pending ? 'Publishing...' : 'Publish'}
</button>
</form>
);
}
Custom Hook
export function useOnlineStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
function handleOnline() { setIsOnline(true); }
function handleOffline() { setIsOnline(false); }
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
return () => {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
};
}, []);
return isOnline;
}
useTransition for Non-Urgent Updates
function SearchableList({ items }: { items: Item[] }) {
const [query, setQuery] = useState('');
const [isPending, startTransition] = useTransition();
const [filteredItems, setFilteredItems] = useState(items);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
startTransition(() => {
setFilteredItems(items.filter(i => i.name.toLowerCase().includes(e.target.value.toLowerCase())));
});
};
return (
<div>
<input value={query} onChange={handleChange} />
{isPending && <span>Filtering...</span>}
<ul>{filteredItems.map(i => <li key={i.id}>{i.name}</li>)}</ul>
</div>
);
}
Best Practices
Server vs Client Decision
- Start with Server Component (no directive needed)
- Add
'use client'only for: hooks, browser APIs, event handlers
State Management
- Keep state minimal — compute derived values during render, not in effects
- Use
useReducerfor state with multiple related actions - Lift state up to the nearest common ancestor
Effects
- Use effects only for external system synchronization
- Always specify correct dependency arrays
- Return cleanup functions for subscriptions and timers
- Never mutate state directly — always create new references
Performance
- With React Compiler: avoid manual
useMemo,useCallback,memo - Without React Compiler: use
useMemofor expensive computations,useCallbackfor stable callbacks - Use
useTransitionfor low-priority state updates - Use stable IDs as list keys, not array indices
React 19 Specifics
- Wrap
use(promise)components in Suspense boundaries - Use
useActionStatefor form-server action integration - Validate Server Action inputs — they are public endpoints
- Pass serializable data from Server to Client Components
Constraints and Warnings
- Server Components: Cannot use hooks, event handlers, or browser APIs
- use() Hook: Can only be called during render, not in callbacks or effects
- Server Actions: Must include
'use server'directive; always validate inputs - State Mutations: Never mutate state directly — always create new references
- Effect Dependencies: Include all dependencies in
useEffectdependency arrays - Memory Leaks: Always clean up subscriptions and event listeners in useEffect return
References
Consult these files for detailed patterns:
- references/hooks-patterns.md — useState, useEffect, useRef, useReducer, custom hooks, common pitfalls
- references/component-patterns.md — Props, composition, lifting state, context, compound components, error boundaries
- references/react19-features.md — use(), useOptimistic, useFormStatus, useActionState, Server Actions, Server Components, migration guide
- references/performance-patterns.md — React Compiler setup, useMemo, useCallback, useTransition, useDeferredValue, lazy loading
- references/typescript-patterns.md — Typed props, generic components, event handlers, discriminated unions, context typing
- references/learn.md — Progressive learning guide from basics to advanced React 19
- references/reference.md — Complete API reference for all React hooks and component APIs
Related skills
More from giuseppe-trisciuoglio/developer-kit and the wider catalog.

shadcn-ui
Copy-owned, accessible React components built on Radix UI and Tailwind CSS with form validation and theming.

sonarqube-mcp
Check SonarQube/SonarCloud quality gates, discover issues, and analyze code before committing.

specs-code-cleanup
Final code cleanup after review: removes debug logs, dead code, and improves readability.

spring-ai-mcp-server-patterns
Spring Boot MCP server patterns for AI function calling and tool handlers with Spring AI

spring-boot-actuator
Production-grade monitoring, health checks, and metrics for Spring Boot services via Actuator and Micrometer.

spring-boot-cache
Configure Spring Boot caching with Redis/Caffeine/EhCache, TTL policies, and @Cacheable/@CacheEvict annotations.