From 7df72d86ea5e20ec19daeb9268150f92a4886601 Mon Sep 17 00:00:00 2001 From: Gildas Garcia Date: Thu, 5 Sep 2019 15:06:04 +0200 Subject: [PATCH] Ensure DeleteButton is usable when record is not defined at mount time --- .../src/button/DeleteWithConfirmButton.js | 24 +++++++++++------ .../src/button/DeleteWithUndoButton.js | 26 ++++++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.js b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.js index e05e343c15d..000e7d66d07 100644 --- a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.js +++ b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.js @@ -1,4 +1,4 @@ -import React, { Fragment, useState } from 'react'; +import React, { Fragment, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import { makeStyles } from '@material-ui/core/styles'; import { fade } from '@material-ui/core/styles/colorManipulator'; @@ -64,7 +64,12 @@ const DeleteWithConfirmButton = ({ const redirect = useRedirect(); const refresh = useRefresh(); const classes = useStyles({ classes: classesOverride }); - const [deleteOne, { loading }] = useDelete(resource, record.id, record, { + + // We don't pass the action payload (the record and its identifier) at + // declaration time to avoid errors for people using the button in a + // component which may not have the record loaded immediately (for exemple + // in the actions of an Edit component) + const [deleteOne, { loading }] = useDelete(resource, undefined, undefined, { onSuccess: () => { notify('ra.notification.deleted', 'info', { smart_count: 1 }); redirect(redirectTo, basePath); @@ -90,12 +95,15 @@ const DeleteWithConfirmButton = ({ e.stopPropagation(); }; - const handleDelete = () => { - deleteOne(); - if (typeof onClick === 'function') { - onClick(); - } - }; + const handleDelete = useCallback( + event => { + deleteOne(event, { id: record.id, previousData: record }); + if (typeof onClick === 'function') { + onClick(); + } + }, + [deleteOne, onClick, record] + ); return ( diff --git a/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.js b/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.js index 899ffc33273..6775fca42f4 100644 --- a/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.js +++ b/packages/ra-ui-materialui/src/button/DeleteWithUndoButton.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import PropTypes from 'prop-types'; import { makeStyles } from '@material-ui/core/styles'; import { fade } from '@material-ui/core/styles/colorManipulator'; @@ -55,7 +55,12 @@ const DeleteWithUndoButton = ({ const notify = useNotify(); const redirect = useRedirect(); const refresh = useRefresh(); - const [deleteOne, { loading }] = useDelete(resource, record.id, record, { + + // We don't pass the action payload (the record and its identifier) at + // declaration time to avoid errors for people using the button in a + // component which may not have the record loaded immediately (for exemple + // in the actions of an Edit component) + const [deleteOne, { loading }] = useDelete(resource, undefined, undefined, { onSuccess: () => { notify('ra.notification.deleted', 'info', { smart_count: 1 }, true); redirect(redirectTo, basePath); @@ -70,13 +75,16 @@ const DeleteWithUndoButton = ({ ), undoable: true, }); - const handleDelete = event => { - event.stopPropagation(); - deleteOne(); - if (typeof onClick === 'function') { - onClick(); - } - }; + const handleDelete = useCallback( + event => { + event.stopPropagation(); + deleteOne(event, { id: record.id, previousData: record }); + if (typeof onClick === 'function') { + onClick(); + } + }, + [deleteOne, onClick, record] + ); return (