---
id: "packages/active-grid/api/use-grid-mutation"
title: "Use grid mutation"
description: "useGridMutation, GridMutationOptions, GridMutationResult, GridMutationStrategy and 1 more: generated from the source of active-grid."
url: "/packages/active-grid/api/use-grid-mutation"
locale: "en"
revision: "g0mvjxwj5c-88bdbe1c:use-grid-mutation"
---

# Use grid mutation

Exported by `@workspace/active-grid`. Generated from the package source; part of [the index of every export](/packages/active-grid/api).

## Functions, hooks and constants

**useGridMutation**: `(gridRef: RefObject<GridImperativeHandle \| null>) => UseGridMutationResult`

One-stop hook for the "run async mutation, then patch the grid" pattern.

Replaces direct `gridRef.current?.removeRow(id)` / `.refetch()` /
`.resetSelection()` calls in consumer-code. The grid's imperative API
remains as a package-internal primitive — consumers should reach for
`useGridMutation` instead, so the strategy choice is named and reviewable.

Returns an object with:

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `mutate` | `<TInput, TActionResult extends { success: true; data: unknown; } \| { success: false; error: unknown; }>(input: TInput, options: GridMutationOptions<TInput, TActionResult>) => Promise<TActionResult>` | yes | Run a mutation. Applies `onSuccess`-strategy when the action resolves to `success: true`. Returns the action's result so the caller can decide on its own toast / dialog behavior.  The return type preserves the action's exact shape — typed errors like `ActionError` survive narrowing on `result.success === false`.  Throws are surfaced to the caller — the hook does not swallow unexpected errors. Use try/catch if the action might throw. |
| `isPending` | `boolean` | yes | Whether any mutation triggered by this hook is currently in flight. |

## Types

**GridMutationOptions**

```ts
interface GridMutationOptions<TInput, TActionResult> {
  action: (input: TInput) => Promise<TActionResult>;
  onSuccess:
    | GridMutationStrategy<TInput, ExtractData<TActionResult>>
    | GridMutationStrategy<TInput, ExtractData<TActionResult>>[];
}
```

**GridMutationResult**

```ts
type GridMutationResult<TData> =
  {success: true; data: TData} | {success: false; error: unknown};
```

Structural mirror of `ActionResult<T>` from `@workspace/active-types`.
Mirrored here so `@workspace/active-grid` stays platform-agnostic.

The `mutate` function preserves the consumer's exact return shape (via
generic inference on the `action` callback) so error-narrowing — e.g.
`toastActionError(result, t, tDynamic)` — keeps working with consumer-specific
error types like `ActionError`.

**GridMutationStrategy**

```ts
type GridMutationStrategy<TInput, TData> =
  | {
      type: 'removeRow';
      rowId: string | ((input: TInput, data: TData) => string);
    }
  | {type: 'addRow'; row: (input: TInput, data: TData) => unknown}
  | {type: 'refetch'}
  | {type: 'resetSelection'}
  | {type: 'none'};
```

Strategy applied to the grid after a successful mutation.

- `removeRow` — drop one row from the local cache (server-mode) without
refetching, preserving session-state (sort/filter/scroll). Like every
strategy here it runs only AFTER the action resolved successfully; it is
not optimistic. An optimistic path with rollback is the deferred F-13.
- `addRow` — append a row to the local cache (server-mode), increments
total-count.
- `refetch` — invalidate cache and re-fetch the current page. Use when
the change cascades to other rows (e.g. status transition affecting
filters, or anonymize/restore).
- `resetSelection` — clear all selected rows. Typical after a bulk
action where the selection should not survive.
- `none` — perform no grid action; consumer-side state is reconciled
elsewhere (e.g. parent re-renders with new props).

**UseGridMutationResult**

```ts
interface UseGridMutationResult {
  mutate: <
    TInput,
    TActionResult extends
      {success: true; data: unknown} | {success: false; error: unknown},
  >(
    input: TInput,
    options: GridMutationOptions<TInput, TActionResult>,
  ) => Promise<TActionResult>;
  isPending: boolean;
}
```
