<UpdateButton>

This component allows to create a button that updates a record by calling the useUpdate hook.

Usage

Use <UpdateButton> inside the actions toolbar of the Edit or Show views.

import { Edit, SimpleForm, TextInput, TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton label="Reset views" data={{ views: 0 }} />
    </TopToolbar>
);

export const PostEdit = () => (
    <Edit actions={<PostEditActions />}>
        <SimpleForm>
            <TextInput source="title" />
            <TextInput source="body" />
        </SimpleForm>
    </Edit>
);

Props

<UpdateButton> accepts the following props:

Prop Required Type Default Description
data Required object   The data used to update the record
mutationMode Optional string undoable Mutation mode ('undoable', 'pessimistic' or 'optimistic')
confirmTitle Optional ReactNode ra.message.bulk_update_title The title of the confirmation dialog when mutationMode is not undoable
confirmContent Optional ReactNode ra.message.bulk_update_content The content of the confirmation dialog when mutationMode is not undoable
mutationOptions Optional Object   The react-query mutation options

<UpdateButton> also accepts the Button props.

data

The data used to update the record. Passed to the dataProvider.update method. This prop is required.

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton label="Reset views" data={{ views: 0 }} />
    </TopToolbar>
);

mutationMode

The mutation mode determines when the side effects (redirection, notifications, etc.) are executed:

  • pessimistic: The mutation is passed to the dataProvider first. When the dataProvider returns successfully, the mutation is applied locally, and the side effects are executed.
  • optimistic: The mutation is applied locally and the side effects are executed immediately. Then the mutation is passed to the dataProvider. If the dataProvider returns successfully, nothing happens (as the mutation was already applied locally). If the dataProvider returns in error, the page is refreshed and an error notification is shown.
  • undoable (default): The mutation is applied locally and the side effects are executed immediately. Then a notification is shown with an undo button. If the user clicks on undo, the mutation is never sent to the dataProvider, and the page is refreshed. Otherwise, after a 5 seconds delay, the mutation is passed to the dataProvider. If the dataProvider returns successfully, nothing happens (as the mutation was already applied locally). If the dataProvider returns in error, the page is refreshed and an error notification is shown.

By default, the <UpdateButton> uses the undoable mutation mode. This is part of the “optimistic rendering” strategy of react-admin ; it makes user interactions more reactive.

You can change this default by setting the mutationMode prop. For instance, to remove the ability to undo the changes, use the optimistic mode:

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton label="Reset views" data={{ views: 0 }} mutationMode="optimistic" />
    </TopToolbar>
);

And to make the action blocking, and wait for the dataProvider response to continue, use the pessimistic mode:

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton label="Reset views" data={{ views: 0 }} mutationMode="pessimistic" />
    </TopToolbar>
);

Tip: When using any other mode than undoable, the <UpdateButton> displays a confirmation dialog before calling the dataProvider.

confirmTitle

Only used when mutationMode is either optimistic or pessimistic to change the confirmation dialog title:

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton
            label="Reset views"
            data={{ views: 0 }}
            mutationMode="optimistic"
            confirmTitle="Reset views"
        />
    </TopToolbar>
);

confirmContent

Only used when mutationMode is either optimistic or pessimistic to change the confirmation dialog content:

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton
            label="Reset views"
            data={{ views: 0 }}
            mutationMode="optimistic"
            confirmContent="Do you really want to reset the views?"
        />
    </TopToolbar>
);

mutationOptions

<UpdateButton> calls dataProvider.update() via react-query’s useMutation hook. You can customize the options you pass to this hook, e.g. to pass a custom meta to the dataProvider.update() call.

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton
            label="Reset views"
            data={{ views: 0 }}
            mutationOptions={{ meta: { foo: 'bar' } }}
        />
    </TopToolbar>
);

You can also use mutationOptions to override success or error side effects, by setting the mutationOptions prop. Refer to the useMutation documentation in the react-query website for a list of the possible options.

Let’s see an example with the success side effect. By default, when the action succeeds, react-admin shows a notification, and refreshes the view. You can override this behavior and pass custom success side effects by providing a mutationOptions prop with an onSuccess key:

import * as React from 'react';
import { useNotify, useRefresh, useRedirect, TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => {
    const notify = useNotify();
    const redirect = useRedirect();

    const onSuccess = () => {
        notify(`Changes saved`);
        redirect('/posts');
    };

    return (
        <TopToolbar>
            <UpdateButton
                label="Reset views"
                data={{ views: 0 }}
                mutationOptions={{ onSuccess }}
            />
        </TopToolbar>
    );
}

The default onSuccess function is:

() => {
    notify('ra.notification.updated', {
        messageArgs: { smart_count: 1 },
        undoable: mutationMode === 'undoable'
    });
}

Tip: When you use mutationMode="pessimistic", the onSuccess function receives the response from the dataProvider.update() call, which is the edited record (see the dataProvider documentation for details). You can use that response in the success side effects:

import * as React from 'react';
import { useNotify, useRefresh, useRedirect, TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => {
    const notify = useNotify();
    const redirect = useRedirect();

    const onSuccess = (data) => {
        notify(`Changes to post "${data.title}" saved`);
        redirect('/posts');
    };

    return (
        <TopToolbar>
            <UpdateButton
                label="Reset views"
                data={{ views: 0 }}
                mutationOptions={{ onSuccess }}
            />
        </TopToolbar>
    );
}

Similarly, you can override the failure side effects with an onError option. By default, when the save action fails at the dataProvider level, react-admin shows a notification error.

import * as React from 'react';
import { useNotify, useRefresh, useRedirect, TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => {
    const notify = useNotify();
    const refresh = useRefresh();
    const redirect = useRedirect();

    const onError = (error) => {
        notify(`Could not edit post: ${error.message}`);
        redirect('/posts');
        refresh();
    };

    return (
        <TopToolbar>
            <UpdateButton
                label="Reset views"
                data={{ views: 0 }}
                mutationOptions={{ onError }}
            />
        </TopToolbar>
    );
}

The onError function receives the error from the dataProvider.update() call. It is a JavaScript Error object (see the dataProvider documentation for details).

The default onError function is:

(error) => {
    notify(typeof error === 'string' ? error : error.message || 'ra.notification.http_error', { type: 'error' });
}

sx

The sx prop lets you style the component and its children using Material-ui’s sx syntax.

import { TopToolbar, UpdateButton } from 'react-admin';

const PostEditActions = () => (
    <TopToolbar>
        <UpdateButton label="Reset views" data={{ views: 0 }} sx={{ width: 500 }} />
    </TopToolbar>
);