AI State Management Advanced

As your AI app grows, you need to manage multiple conversations, persist message history, handle optimistic updates, and coordinate state across components. This lesson covers the patterns and tools for managing AI state at scale.

Multi-Conversation Support

Use the id parameter to manage multiple independent conversations:

TypeScript
import { useChat } from '@ai-sdk/react';

function ChatWindow({ conversationId }: { conversationId: string }) {
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    id: conversationId,                  // Unique ID per conversation
    api: '/api/chat',
    body: { conversationId },            // Send to server for context
    initialMessages: [],                 // Load from storage if needed
  });

  // Each conversationId gets its own message state
  return ( /* ... render chat ... */ );
}

Persisting Conversations

Save conversation history to localStorage or a database:

TypeScript - hooks/usePersistedChat.ts
import { useChat } from '@ai-sdk/react';
import { useEffect } from 'react';

export function usePersistedChat(id: string) {
  const stored = localStorage.getItem(`chat-${id}`);
  const initialMessages = stored ? JSON.parse(stored) : [];

  const chat = useChat({
    id,
    api: '/api/chat',
    initialMessages,
    onFinish: () => {
      // Save after each completed response
      localStorage.setItem(`chat-${id}`, JSON.stringify(chat.messages));
    },
  });

  return chat;
}

Conversation List with Context

TypeScript - context/ChatContext.tsx
import { createContext, useContext, useState, ReactNode } from 'react';

interface Conversation { id: string; title: string; }

interface ChatContextType {
  conversations: Conversation[];
  activeId: string | null;
  createConversation: () => void;
  selectConversation: (id: string) => void;
}

const ChatContext = createContext<ChatContextType>(null!);

export function ChatProvider({ children }: { children: ReactNode }) {
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [activeId, setActiveId] = useState<string | null>(null);

  function createConversation() {
    const id = crypto.randomUUID();
    setConversations(prev => [...prev, { id, title: 'New Chat' }]);
    setActiveId(id);
  }

  return (
    <ChatContext.Provider value={{ conversations, activeId, createConversation, selectConversation: setActiveId }}>
      {children}
    </ChatContext.Provider>
  );
}

export const useChatContext = () => useContext(ChatContext);

Trimming Message History

Token Management: LLMs have context limits. When sending messages to the API, trim the history to the most recent N messages or implement a sliding window. Keep the system prompt and the last 10-20 messages for the best balance of context and cost.

State Management Complete!

You can now manage complex AI state across your React app. In the final lesson, learn production best practices.

Next: Best Practices →