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