TanStackT
TanStack5w ago
2 replies
worthy-azure

Tracking pending state of single item during mutation?

I'm using inserts and want to disable certain actions (like delete) while an item is still being persisted.

const TodoItem = ({ todo, isPending }: { todo: Todo, isPersisted: boolean }) => {
  return (
    <div>
      {todo.text}
      <button
        onClick={() => todoCollection.delete(todo.id)}
        disabled={isPending}
      >
        Delete
      </button>
    </div>
  )
}


I can't find out how to get the isPending in a sane way.

Currently, I'm manually tracking pending IDs with external state and this feels quite tedious
const [pendingIds, setPendingIds] = useState<Set<string>>(new Set())

const handleCreate = () => {
  const id = crypto.randomUUID()
  
  setPendingIds(prev => new Set(prev).add(id))
  
  const tx = todoCollection.insert({ id, text: 'New todo', completed: false })
  
  tx.isPersisted.promise.finally(() => {
    setPendingIds(prev => {
      const next = new Set(prev)
      next.delete(id)
      return next
    })
  })
}

// In render:
<TodoItem todo={todo} isPending={pendingIds.has(todo.id)} />


This works but feels verbose for something the library must already track internally. Also this won't work on a global level if I want to check a pending state in another branch of the JSX tree.

Is there a built-in way to check if an item has a pending transaction? Something like:

// Ideal API - any of these would work:
const { data, pendingKeys } = useLiveQuery(...)
// or
todoCollection.hasPendingMutation(id)
// or
const isPending = usePendingMutation(todoCollection, id)


Any good ideas out there?
Was this page helpful?