Install
$ agentstack add skill-jh941213-codex-lattice-react-patterns ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
React Development Patterns
Expert guide for building modern React 19 applications with new concurrent features, Server Components, Actions, and advanced patterns.
When to Use
- Building React 19 components with TypeScript/JavaScript
- Managing component state with useState and useReducer
- Handling side effects with useEffect
- Optimizing performance with useMemo and useCallback
- Creating custom hooks for reusable logic
- Implementing component composition patterns
- Working with refs using useRef
- Using React 19's new features (use(), useOptimistic, useFormStatus)
- Implementing Server Components and Actions
- Working with Suspense and concurrent rendering
- Building forms with new form hooks
Core Hooks Patterns
useState - State Management
Basic state declaration and updates:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
setCount(count + 1)}>
Count: {count}
);
}
State with initializer function (expensive computation):
const [state, setState] = useState(() => {
const initialState = computeExpensiveValue();
return initialState;
});
Multiple state variables:
function UserProfile() {
const [name, setName] = useState('');
const [age, setAge] = useState(0);
const [email, setEmail] = useState('');
return (
setName(e.target.value)} />
setAge(Number(e.target.value))} />
setEmail(e.target.value)} />
);
}
useEffect - Side Effects
Basic effect with cleanup:
import { useEffect } from 'react';
function ChatRoom({ roomId }: { roomId: string }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
// Cleanup function
return () => {
connection.disconnect();
};
}, [roomId]); // Dependency array
return Connected to {roomId};
}
Effect with multiple dependencies:
function ChatRoom({ roomId, serverUrl }: { roomId: string; serverUrl: string }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId, serverUrl]); // Re-run when either changes
return Welcome to {roomId};
}
Effect for subscriptions:
function StatusBar() {
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);
};
}, []); // Empty array = run once on mount
return {isOnline ? '✅ Online' : '❌ Disconnected'};
}
useRef - Persistent References
Storing mutable values without re-renders:
import { useRef } from 'react';
function Timer() {
const intervalRef = useRef(null);
const startTimer = () => {
intervalRef.current = setInterval(() => {
console.log('Tick');
}, 1000);
};
const stopTimer = () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
return (
<>
Start
Stop
);
}
DOM element references:
function TextInput() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current?.focus();
};
return (
<>
Focus Input
);
}
Custom Hooks Pattern
Extract reusable logic into custom hooks:
// useOnlineStatus.ts
import { useState, useEffect } from 'react';
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;
}
// Usage in components
function StatusBar() {
const isOnline = useOnlineStatus();
return {isOnline ? '✅ Online' : '❌ Disconnected'};
}
function SaveButton() {
const isOnline = useOnlineStatus();
return (
{isOnline ? 'Save' : 'Reconnecting...'}
);
}
Custom hook with parameters:
// useChatRoom.ts
import { useEffect } from 'react';
interface ChatOptions {
serverUrl: string;
roomId: string;
}
export function useChatRoom({ serverUrl, roomId }: ChatOptions) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [serverUrl, roomId]);
}
// Usage
function ChatRoom({ roomId }: { roomId: string }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useChatRoom({ serverUrl, roomId });
return (
<>
setServerUrl(e.target.value)} />
Welcome to {roomId}
);
}
Component Composition Patterns
Props and Children
Basic component with props:
interface ButtonProps {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
onClick?: () => void;
children: React.ReactNode;
}
function Button({ variant = 'primary', size = 'md', onClick, children }: ButtonProps) {
return (
{children}
);
}
Composition with children:
interface CardProps {
children: React.ReactNode;
className?: string;
}
function Card({ children, className = '' }: CardProps) {
return (
{children}
);
}
// Usage
function UserProfile() {
return (
John Doe
Software Engineer
);
}
Lifting State Up
Shared state between siblings:
function Parent() {
const [activeIndex, setActiveIndex] = useState(0);
return (
<>
setActiveIndex(0)}
>
Panel 1 content
setActiveIndex(1)}
>
Panel 2 content
);
}
interface PanelProps {
isActive: boolean;
onShow: () => void;
children: React.ReactNode;
}
function Panel({ isActive, onShow, children }: PanelProps) {
return (
Show
{isActive && {children}}
);
}
Performance Optimization
Avoid Unnecessary Effects
❌ Bad - Using effect for derived state:
function TodoList({ todos }: { todos: Todo[] }) {
const [visibleTodos, setVisibleTodos] = useState([]);
useEffect(() => {
setVisibleTodos(todos.filter(t => !t.completed));
}, [todos]); // Unnecessary effect
return {/* ... */};
}
✅ Good - Compute during render:
function TodoList({ todos }: { todos: Todo[] }) {
const visibleTodos = todos.filter(t => !t.completed); // Direct computation
return {/* ... */};
}
useMemo for Expensive Computations
import { useMemo } from 'react';
function DataTable({ data }: { data: Item[] }) {
const sortedData = useMemo(() => {
return [...data].sort((a, b) => a.name.localeCompare(b.name));
}, [data]); // Only recompute when data changes
return {/* render sortedData */};
}
useCallback for Function Stability
import { useCallback } from 'react';
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Clicked', count);
}, [count]); // Recreate only when count changes
return ;
}
TypeScript Best Practices
Type-Safe Props
interface UserProps {
id: string;
name: string;
email: string;
age?: number; // Optional
}
function User({ id, name, email, age }: UserProps) {
return (
{name}
{email}
{age && Age: {age}}
);
}
Generic Components
interface ListProps {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List({ items, renderItem }: ListProps) {
return (
{items.map((item, index) => (
{renderItem(item)}
))}
);
}
// Usage
{user.name}}
/>
Event Handlers
function Form() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Handle form submission
};
const handleChange = (e: React.ChangeEvent) => {
console.log(e.target.value);
};
return (
);
}
Common Patterns
Controlled Components
function ControlledInput() {
const [value, setValue] = useState('');
return (
setValue(e.target.value)}
/>
);
}
Conditional Rendering
function Greeting({ isLoggedIn }: { isLoggedIn: boolean }) {
return (
{isLoggedIn ? (
) : (
)}
);
}
Lists and Keys
function UserList({ users }: { users: User[] }) {
return (
{users.map(user => (
{user.name}
))}
);
}
Best Practices
General React Best Practices
- Dependency Arrays: Always specify correct dependencies in useEffect
- State Structure: Keep state minimal and avoid redundant state
- Component Size: Keep components small and focused
- Custom Hooks: Extract complex logic into reusable custom hooks
- TypeScript: Use TypeScript for type safety
- Keys: Use stable IDs as keys for list items, not array indices
- Immutability: Never mutate state directly
- Effects: Use effects only for synchronization with external systems
- Performance: Profile before optimizing with useMemo/useCallback
React 19 Specific Best Practices
- Server Components: Use Server Components for data fetching and static content
- Client Components: Mark components as 'use client' only when necessary
- Actions: Use Server Actions for mutations and form submissions
- Optimistic Updates: Implement useOptimistic for better UX
- use() Hook: Use for reading promises and context conditionally
- Form State: Use useFormState and useFormStatus for complex forms
- Concurrent Features: Leverage useTransition for non-urgent updates
- Error Boundaries: Implement proper error handling with error boundaries
Common Pitfalls
General React Pitfalls
❌ Missing Dependencies:
useEffect(() => {
// Uses 'count' but doesn't include it in deps
console.log(count);
}, []); // Wrong!
❌ Mutating State:
const [items, setItems] = useState([]);
items.push(newItem); // Wrong! Mutates state
setItems(items); // Won't trigger re-render
✅ Correct Approach:
setItems([...items, newItem]); // Create new array
React 19 Specific Pitfalls
❌ Using use() outside of render:
// Wrong!
function handleClick() {
const data = use(promise); // Error: use() can only be called in render
}
✅ Correct usage:
function Component({ promise }) {
const data = use(promise); // Correct: called during render
return {data};
}
❌ Forgetting 'use server' directive:
// Wrong - missing 'use server'
export async function myAction() {
// This will run on the client!
}
✅ Correct Server Action:
'use server'; // Must be at the top
export async function myAction() {
// Now runs on the server
}
❌ Mixing Server and Client logic incorrectly:
// Wrong - trying to use browser APIs in Server Component
export default async function ServerComponent() {
const width = window.innerWidth; // Error: window is not defined
return {width};
}
✅ Correct separation:
// Server Component for data
export default async function ServerComponent() {
const data = await fetchData();
return ;
}
// Client Component for browser APIs
'use client';
function ClientComponent({ data }) {
const [width, setWidth] = useState(window.innerWidth);
// Handle resize logic...
return {width};
}
React 19 New Features
use() Hook - Reading Resources
The use() hook reads the value from a resource like a Promise or Context:
import { use } from 'react';
// Reading a Promise in a component
function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
return {message};
}
// Reading Context conditionally
function Button() {
if (condition) {
const theme = use(ThemeContext);
return Click;
}
return Click;
}
useOptimistic Hook - Optimistic UI Updates
Manage optimistic UI updates for async operations:
import { useOptimistic } from 'react';
function TodoList({ todos, addTodo }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo) => [...state, newTodo]
);
const handleSubmit = async (formData) => {
const newTodo = { id: Date.now(), text: formData.get('text') };
// Optimistically add to UI
addOptimisticTodo(newTodo);
// Actually add to backend
await addTodo(newTodo);
};
return (
{optimisticTodos.map(todo => (
{todo.text}
))}
Add Todo
);
}
useFormStatus Hook - Form State
Access form submission status from child components:
import { useFormStatus } from 'react';
function SubmitButton() {
const { pending, data } = useFormStatus();
return (
{pending ? 'Submitting...' : 'Submit'}
);
}
function ContactForm() {
return (
);
}
useFormState Hook - Form State Management
Manage form state with error handling:
import { useFormState } from 'react';
async function submitAction(prevState: string | null, formData: FormData) {
const email = formData.get('email') as string;
if (!email.includes('@')) {
return 'Invalid email address';
}
await submitToDatabase(email);
return null;
}
function EmailForm() {
const [state, formAction] = useFormState(submitAction, null);
return (
Subscribe
{state && {state}}
);
}
Server Actions
Define server-side functions for form handling:
// app/actions.ts
'use server';
import { redirect } from 'next/navigation';
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
const content = formData.get('content') as string;
// Validate input
if (!title || !content) {
return { error: 'Title and content are required' };
}
// Save to database
const post = await db.post.create({
data: { title, content }
});
// Update cache and redirect
revalidatePath('/posts');
redirect(`/posts/${post.id}`);
}
Server Components
Components that run exclusively on the server:
// app/posts/page.tsx - Server Component
async function PostsPage() {
// Server-side data fetching
const posts = await db.post.findMany({
orderBy: { createdAt: 'desc' },
take: 10
});
return (
Latest Posts
);
}
// Client Component for interactivity
'use client';
function PostsList({ posts }: { posts: Post[] }) {
const [selectedId, setSelectedId] = useState(null);
return (
{posts.map(post => (
setSelectedId(post.id)}
className={selectedId === post.id ? 'selected' : ''}
>
{post.title}
))}
);
}
React Compiler
Automatic Optimization
React Compiler automatically optimizes your components:
// Before React Compiler - manual memoization needed
const ExpensiveComponent = memo(function ExpensiveComponent({
data,
onUpdate
}) {
const processedData = useMemo(() => {
return data.map(item => (
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [jh941213](https://github.com/jh941213)
- **Source:** [jh941213/codex-lattice](https://github.com/jh941213/codex-lattice)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.