<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>
);
