typescriptadvanced

Optimistic List with Rollback

A list component that immediately reflects mutations and rolls back on server error.

typescript
import { useState, useCallback } from 'react';

interface Item {
  id: string;
  text: string;
}

export function useOptimisticList(initial: Item[]) {
  const [items, setItems] = useState(initial);

  const addItem = useCallback(async (item: Item, serverFn: () => Promise<void>) => {
    setItems(prev => [...prev, item]);
    try {
      await serverFn();
    } catch {
      setItems(prev => prev.filter(i => i.id !== item.id));
      throw new Error('Failed to add item');
    }
  }, []);

  const removeItem = useCallback(async (id: string, serverFn: () => Promise<void>) => {
    const backup = items;
    setItems(prev => prev.filter(i => i.id !== id));
    try {
      await serverFn();
    } catch {
      setItems(backup);
      throw new Error('Failed to remove item');
    }
  }, [items]);

  return { items, addItem, removeItem };
}

Use Cases

  • Todo lists
  • Real-time collaborative editing

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.