# React Patterns

> |

- **Type:** Skill
- **Install:** `agentstack add skill-jh941213-codex-lattice-react-patterns`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [jh941213](https://agentstack.voostack.com/s/jh941213)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [jh941213](https://github.com/jh941213)
- **Source:** https://github.com/jh941213/codex-lattice/tree/main/skills/react-patterns

## Install

```sh
agentstack add skill-jh941213-codex-lattice-react-patterns
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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:

```typescript
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
     setCount(count + 1)}>
      Count: {count}
    
  );
}
```

State with initializer function (expensive computation):

```typescript
const [state, setState] = useState(() => {
  const initialState = computeExpensiveValue();
  return initialState;
});
```

Multiple state variables:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
function TextInput() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current?.focus();
  };

  return (
    <>
      
      Focus Input
    
  );
}
```

## Custom Hooks Pattern

Extract reusable logic into custom hooks:

```typescript
// 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:

```typescript
// 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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
function TodoList({ todos }: { todos: Todo[] }) {
  const [visibleTodos, setVisibleTodos] = useState([]);

  useEffect(() => {
    setVisibleTodos(todos.filter(t => !t.completed));
  }, [todos]); // Unnecessary effect

  return {/* ... */};
}
```

✅ Good - Compute during render:

```typescript
function TodoList({ todos }: { todos: Todo[] }) {
  const visibleTodos = todos.filter(t => !t.completed); // Direct computation

  return {/* ... */};
}
```

### useMemo for Expensive Computations

```typescript
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

```typescript
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

```typescript
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

```typescript
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

```typescript
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

```typescript
function ControlledInput() {
  const [value, setValue] = useState('');

  return (
     setValue(e.target.value)}
    />
  );
}
```

### Conditional Rendering

```typescript
function Greeting({ isLoggedIn }: { isLoggedIn: boolean }) {
  return (
    
      {isLoggedIn ? (
        
      ) : (
        
      )}
    
  );
}
```

### Lists and Keys

```typescript
function UserList({ users }: { users: User[] }) {
  return (
    
      {users.map(user => (
        
          {user.name}
        
      ))}
    
  );
}
```

## Best Practices

### General React Best Practices

1. **Dependency Arrays**: Always specify correct dependencies in useEffect
2. **State Structure**: Keep state minimal and avoid redundant state
3. **Component Size**: Keep components small and focused
4. **Custom Hooks**: Extract complex logic into reusable custom hooks
5. **TypeScript**: Use TypeScript for type safety
6. **Keys**: Use stable IDs as keys for list items, not array indices
7. **Immutability**: Never mutate state directly
8. **Effects**: Use effects only for synchronization with external systems
9. **Performance**: Profile before optimizing with useMemo/useCallback

### React 19 Specific Best Practices

1. **Server Components**: Use Server Components for data fetching and static content
2. **Client Components**: Mark components as 'use client' only when necessary
3. **Actions**: Use Server Actions for mutations and form submissions
4. **Optimistic Updates**: Implement useOptimistic for better UX
5. **use() Hook**: Use for reading promises and context conditionally
6. **Form State**: Use useFormState and useFormStatus for complex forms
7. **Concurrent Features**: Leverage useTransition for non-urgent updates
8. **Error Boundaries**: Implement proper error handling with error boundaries

## Common Pitfalls

### General React Pitfalls

❌ **Missing Dependencies**:
```typescript
useEffect(() => {
  // Uses 'count' but doesn't include it in deps
  console.log(count);
}, []); // Wrong!
```

❌ **Mutating State**:
```typescript
const [items, setItems] = useState([]);
items.push(newItem); // Wrong! Mutates state
setItems(items); // Won't trigger re-render
```

✅ **Correct Approach**:
```typescript
setItems([...items, newItem]); // Create new array
```

### React 19 Specific Pitfalls

❌ **Using use() outside of render**:
```typescript
// Wrong!
function handleClick() {
  const data = use(promise); // Error: use() can only be called in render
}
```

✅ **Correct usage**:
```tsx
function Component({ promise }) {
  const data = use(promise); // Correct: called during render
  return {data};
}
```

❌ **Forgetting 'use server' directive**:
```typescript
// Wrong - missing 'use server'
export async function myAction() {
  // This will run on the client!
}
```

✅ **Correct Server Action**:
```typescript
'use server'; // Must be at the top

export async function myAction() {
  // Now runs on the server
}
```

❌ **Mixing Server and Client logic incorrectly**:
```tsx
// 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**:
```tsx
// 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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
// 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:

```typescript
// 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:

```typescript
// 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.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jh941213-codex-lattice-react-patterns
- Seller: https://agentstack.voostack.com/s/jh941213
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
