Skip to main content
useUpdate is a modified version of TanStack Query’s useMutation for update mutations. It uses the update method from the dataProvider and supports optimistic updates, pessimistic updates, and undoable mutations.

Usage

import { useUpdate } from "@refinedev/core";

interface IProduct {
  id: number;
  name: string;
  price: number;
}

const { mutate } = useUpdate<IProduct>();

mutate({
  resource: "products",
  id: 1,
  values: {
    name: "Updated Product",
    price: 149.99,
  },
});

Parameters

You can pass parameters either to the hook or to the mutate/mutateAsync functions. Parameters passed to the mutation functions override those passed to the hook.
resource
string
Resource name for API data interactions.
id
BaseKey
required
ID of the record to update. Can be a string or number.
values
TVariables
required
Values for the mutation function - the data to update.
mutationMode
'pessimistic' | 'optimistic' | 'undoable'
Determines when mutations are executed. Defaults to the global mutation mode.
  • pessimistic: Updates are applied after the server responds
  • optimistic: Updates are applied immediately, rolled back on error
  • undoable: Updates are applied immediately with an option to undo
undoableTimeout
number
default:"5000"
Duration in milliseconds to wait before executing the mutation when mutationMode is undoable.
onCancel
(cancelMutation: () => void) => void
Callback that provides a function to cancel the mutation when mutationMode is undoable.
meta
MetaQuery
Meta data for the dataProvider. Can be used to pass additional parameters to data provider methods.
dataProviderName
string
default:"default"
If there is more than one dataProvider, you should specify which one to use.
invalidates
Array<keyof IQueryKeys>
default:"['list', 'many', 'detail']"
Specify which queries should be invalidated after successful mutation. Options: 'list', 'many', 'detail', 'resourceAll', 'all'.
optimisticUpdateMap
OptimisticUpdateMapType
Customize optimistic update logic for different query types.
successNotification
OpenNotificationParams | false | ((data, params) => OpenNotificationParams | false)
Success notification configuration. Set to false to disable.
errorNotification
OpenNotificationParams | false | ((error, params) => OpenNotificationParams | false)
Error notification configuration. Set to false to disable.
mutationOptions
UseMutationOptions
TanStack Query’s useMutation options (excluding onMutate).
overtimeOptions
UseLoadingOvertimeOptionsProps
Configuration for loading overtime behavior.

Return Values

mutate
(params?: UpdateParams) => void
Function to trigger the mutation.
mutateAsync
(params?: UpdateParams) => Promise<UpdateResponse<TData>>
Async version that returns a promise.
mutation
UseMutationResult
TanStack Query’s useMutation return object.
overtime
object
Loading overtime information.

Examples

Basic Usage

import { useUpdate } from "@refinedev/core";

const { mutate } = useUpdate();

const handleUpdate = (id: number, values: Partial<IProduct>) => {
  mutate({
    resource: "products",
    id,
    values,
  });
};

With Async/Await

const { mutateAsync } = useUpdate();

const handleUpdate = async (id: number, values: Partial<IProduct>) => {
  try {
    const result = await mutateAsync({
      resource: "products",
      id,
      values,
    });
    console.log("Updated product:", result.data);
  } catch (error) {
    console.error("Failed to update:", error);
  }
};

Optimistic Updates

const { mutate } = useUpdate({
  mutationMode: "optimistic",
});

mutate({
  resource: "products",
  id: 1,
  values: { name: "Updated Name" },
});
// UI updates immediately, reverts on error

Undoable Updates

const { mutate } = useUpdate({
  mutationMode: "undoable",
  undoableTimeout: 5000, // Wait 5 seconds before executing
});

mutate({
  resource: "products",
  id: 1,
  values: { name: "Updated Name" },
  onCancel: (cancelMutation) => {
    // Show undo button
    showUndoButton(() => {
      cancelMutation();
    });
  },
});

Pessimistic Updates (Default)

const { mutate } = useUpdate({
  mutationMode: "pessimistic",
});

mutate({
  resource: "products",
  id: 1,
  values: { name: "Updated Name" },
});
// UI updates only after server confirms

Custom Optimistic Update Logic

const { mutate } = useUpdate({
  mutationMode: "optimistic",
  optimisticUpdateMap: {
    list: (previous, values, id) => {
      if (!previous) return null;
      
      return {
        ...previous,
        data: previous.data.map((item) =>
          item.id === id ? { ...item, ...values } : item
        ),
      };
    },
    detail: true, // Use default behavior
    many: false, // Disable optimistic updates for many queries
  },
});

With Callbacks

const { mutate } = useUpdate({
  mutationOptions: {
    onSuccess: (data) => {
      console.log("Product updated:", data.data);
    },
    onError: (error) => {
      console.error("Error:", error.message);
    },
    onSettled: () => {
      console.log("Mutation completed");
    },
  },
});

Custom Invalidation

const { mutate } = useUpdate();

mutate({
  resource: "products",
  id: 1,
  values: { name: "Updated Name" },
  invalidates: ["list"], // Only invalidate list queries
});

Disable Automatic Invalidation

mutate({
  resource: "products",
  id: 1,
  values: { name: "Updated Name" },
  invalidates: [], // Don't invalidate any queries
});

With Meta Data

const { mutate } = useUpdate();

mutate({
  resource: "products",
  id: 1,
  values: { name: "Updated Name" },
  meta: {
    headers: { "X-Custom-Header": "value" },
  },
});

Pre-configured Hook

const { mutate } = useUpdate({
  resource: "products",
});

// Now you only need to pass id and values
mutate({
  id: 1,
  values: { name: "Updated Name" },
});

Type Parameters

  • TData - Result data type of the mutation. Extends BaseRecord.
  • TError - Custom error type that extends HttpError.
  • TVariables - Type of the values/payload for the mutation.

FAQ

  • Pessimistic: Updates the UI only after the server responds (safest)
  • Optimistic: Updates the UI immediately, reverts on error (best UX)
  • Undoable: Updates UI immediately with an option to cancel before server update (Gmail-style)
Use the optimisticUpdateMap parameter:
const { mutate } = useUpdate({
  mutationMode: "optimistic",
  optimisticUpdateMap: {
    list: true,
    many: false,
    detail: false,
  },
});
Yes, pass only the fields you want to update in values. Most data providers will perform a partial update (PATCH):
mutate({
  resource: "products",
  id: 1,
  values: { price: 199.99 }, // Only update price
});
Validation errors are included in the error object:
const { mutate } = useUpdate({
  mutationOptions: {
    onError: (error) => {
      if (error.errors) {
        // Handle validation errors per field
        console.log(error.errors);
      }
    },
  },
});

Build docs developers (and LLMs) love