diff --git a/docs/Actions.md b/docs/Actions.md
index 3b6ac45b2f3..c38d47ea87c 100644
--- a/docs/Actions.md
+++ b/docs/Actions.md
@@ -620,10 +620,152 @@ const ApproveButton = ({ record }) => {
Fetching data is called a *side effect*, since it calls the outside world, and is asynchronous. Usual actions may have other side effects, like showing a notification, or redirecting the user to another page. React-admin provides the following hooks to handle most common side effects:
-- `useNotify`: Return a function to display a notification. The arguments should be a message (it can be a translation key), a level (either `info`, `success` or `warning`), an `options` object to pass to the `translate` function (in the case of the default i18n provider, using Polyglot.js, it will be the interpolation options used for passing variables), a boolean to set to `true` if the notification should contain an "undo" button and a number corresponding to the notification duration.
-- `useRedirect`: Return a function to redirect the user to another page. The arguments should be the path to redirect the user to, and the current `basePath`.
-- `useRefresh`: Return a function to force a rerender of the current view (equivalent to pressing the Refresh button).
-- `useUnselectAll`: Return a function to unselect all lines in the current `Datagrid`. Pass the name of the resource as argument.
+- [`useNotify`](#usenotify): Return a function to display a notification.
+- [`useRedirect`](#useredirect): Return a function to redirect the user to another page.
+- [`useRefresh`](#userefresh): Return a function to force a rerender of the current view (equivalent to pressing the Refresh button).
+- [`useUnselectAll`](#useunselectall): Return a function to unselect all lines in the current `Datagrid`.
+
+### `useNotify`
+
+This hook returns a function that displays a notification in the bottom of the page.
+
+```jsx
+import { useNotify } from 'react-admin';
+
+const NotifyButton = () => {
+ const notify = useNotify();
+ const handleClick = () => {
+ notify(`Comment approved`, 'success');
+ }
+ return ;
+};
+```
+
+The callback takes 5 arguments:
+ - the message to display
+ - the level of the notification (`info`, `success` or `warning` - the default is `info`)
+ - an `options` object to pass to the `translate` function (because notificatoin messages are translated if your admin has an `i18nProvider`). It is useful for inserting variables into the translation.
+ - an `undoable` boolean. Set it to `true` if the notification should contain an "undo" button
+ - a `duration` number. Set it to `0` if the notification should not be dismissable.
+
+Here are more examples of `useNotify` calls:
+
+```jsx
+// notify a warning
+notify(`This is a warning`, 'warning');
+// pass translation arguments
+notify('item.created', 'info', { resource: 'post' });
+// send an undoable notification
+notify('Element updated', 'info', undefined, true);
+```
+
+**Tip**: When using `useNotify` as a side effect for an `undoable` Edit form, you MUST set the fourth argument to `true`, otherwise the "undo" button will not appear, and the actual update will never occur.
+
+```jsx
+import * as React from 'react';
+import { useNotify, Edit, SimpleForm } from 'react-admin';
+
+const PostEdit = props => {
+ const notify = useNotify();
+
+ const onSuccess = () => {
+ notify(`Changes saved`, undefined, undefined, true);
+ };
+
+ return (
+
+
+ ...
+
+
+ );
+}
+```
+
+### `useRedirect`
+
+This hook returns a function that redirects the user to another page.
+
+```jsx
+import { useRedirect } from 'react-admin';
+
+const DashboardButton = () => {
+ const redirect = useRedirect();
+ const handleClick = () => {
+ redirect('/dashboard');
+ }
+ return ;
+};
+```
+
+The callback takes 3 arguments:
+ - the page to redirect the user to ('list', 'create', 'edit', 'show', or a custom path)
+ - the current `basePath`
+ - the `id` of the record to redirect to (if any)
+
+Here are more examples of `useRedirect` calls:
+
+```jsx
+// redirect to the post list page
+redirect('list', '/posts');
+// redirect to the edit page of a post:
+redirect('edit', '/posts', 1);
+// redirect to the post creation page:
+redirect('create', '/posts');
+```
+
+Note that `useRedirect` doesn't allow to redirect to pages outside the current React app. For that, you should use `document.location`.
+
+### `useRefresh`
+
+This hook returns a function that forces a rerender of the current view.
+
+```jsx
+import { useRefresh } from 'react-admin';
+
+const RefreshButton = () => {
+ const refresh = useRefresh();
+ const handleClick = () => {
+ refresh();
+ }
+ return ;
+};
+```
+
+To make this work, react-admin stores a `version` number in its state. The `useDataProvider()` hook uses this `version` in its effect dependencies. Also, page components use the `version` as `key`. The `refresh` callback increases the `version`, which forces a re-execution all queries based on the `useDataProvider()` hook, and a rerender of all components using the `version` as key.
+
+This means that you can make any component inside a react-admin app refreshable by using the right key:
+
+```jsx
+import * as React from 'react';
+import { useVersion } from 'react-admin';
+
+const MyComponent = () => {
+ const version = useVersion();
+ return
+ ...
+
;
+};
+```
+
+The callback takes 1 argument:
+ - `hard`: when set to true, the callback empties the cache, too
+
+### `useUnselectAll`
+
+This hook returns a function that unselects all lines in the current `Datagrid`. Pass the name of the resource as argument.
+
+```jsx
+import { useUnselectAll } from 'react-admin';
+
+const UnselectAllButton = () => {
+ const unselectAll = useUnselectAll();
+ const handleClick = () => {
+ unselectAll('posts');
+ }
+ return ;
+};
+```
## Handling Side Effects In Other Hooks
diff --git a/docs/Reference.md b/docs/Reference.md
index d6e30346a1a..93ed72c99b6 100644
--- a/docs/Reference.md
+++ b/docs/Reference.md
@@ -181,13 +181,14 @@ title: "Reference"
* `useLogoutIfAccessDenied`
* [`useMediaQuery`](./Theming.md#usemediaquery-hook)
* [`useMutation`](./Actions.md#usemutation-hook)
-* [`useNotify`](./Actions.md#handling-side-effects-in-usedataprovider)
+* [`useNotify`](./Actions.md#usenotify)
* `usePaginationState`
* [`usePermissions`](./Authentication.md#usepermissions-hook)
* [`usePreferences`](https://marmelab.com/ra-enterprise/modules/ra-preferences#usepreferences-reading-and-writing-user-preferences)
* [`useQuery`](./Actions.md#usequery-hook)
* [`useQueryWithStore`](./Actions.md#usequerywithstore-hook)
-* [`useRedirect`](./Actions.md#handling-side-effects-in-usedataprovider)
+* [`useRedirect`](./Actions.md#useredirect)
+* [`useRefresh`](./Actions.md#userefresh)
* [`useResourceAppLocation`](https://marmelab.com/ra-enterprise/modules/ra-navigation#useresourceapplocation-access-current-resource-app-location)
* `useReference`
* `useReferenceArrayFieldController`
@@ -206,7 +207,7 @@ title: "Reference"
* [`useUpdate`](./Actions.md#useupdate)
* `useUpdateLoading`
* [`useUpdateMany`](./Actions.md#useupdatemany)
-* [`useUnselectAll`](./Actions.md#handling-side-effects-in-usedataprovider)
+* [`useUnselectAll`](./Actions.md#useunselectall)
* [`useWarnWhenUnsavedChanges`](./CreateEdit.md#warning-about-unsaved-changes)
* `useVersion`
* [`withDataProvider`](./Actions.md#legacy-components-query-mutation-and-withdataprovider)