首页 > 解决方案 > 保存时反应管理员确认对话框

问题描述

我正在尝试显示有关在 React 管理框架中保存的确认对话框,但保存功能开始中断。

Error
--> Converting circular structure to JSON
--> starting at object with constructor 'FiberNode'
|     property 'stateNode' -> object with constructor 'HTMLButtonElement'
--- property '__reactInternalInstance$mtamow8fbfp' closes the circle

The dataProvider threw an error. It should return a rejected Promise instead.

我怀疑它的重定向问题,但无法弄清楚。

如果我不使用ConfirmationDialog 并调用SaveButtonhandleSave的道具,它会起作用onSave

React 管理员版本 - 3.4.2

这是正确的方法吗?请帮忙

确认.tsx

/**
 * Confirmation dialog
 *
 * @example
 * <Confirm
 *     isOpen={true}
 *     title="Delete Item"
 *     content="Are you sure you want to delete this item?"
 *     confirm="Yes"
 *     confirmColor="primary"
 *     ConfirmIcon=ActionCheck
 *     CancelIcon=AlertError
 *     cancel="Cancel"
 *     onConfirm={() => { // do something }}
 *     onClose={() => { // do something }}
 * />
 */
const Confirm: FC<ConfirmProps> = props => {
  const {
    isOpen = false,
    loading,
    title,
    content,
    confirm,
    cancel,
    confirmColor,
    onClose,
    onConfirm,
    translateOptions = {}
  } = props;
  const classes = useStyles(props);
  // const translate = useTranslate();

  const handleConfirm = useCallback(
    e => {
      e.stopPropagation();
      onConfirm(e);
    },
    [onConfirm]
  );

  const handleClick = useCallback(e => {
    e.stopPropagation();
  }, []);

  return (
    <Dialog
      open={isOpen}
      onClose={onClose}
      onClick={handleClick}
      aria-labelledby="alert-dialog-title"
    >
      <DialogTitle id="alert-dialog-title">{title}</DialogTitle>
      <DialogContent>
        <DialogContentText className={classes.contentText}>
          {content}
        </DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button
          disabled={loading}
          onClick={onClose}
          className={classnames("ra-confirm", {
            [classes.confirmWarning]: confirmColor === "primary"
          })}
        >
          <CancelIcon className={classes.iconPaddingStyle} />
          {cancel}
        </Button>
        <Button
          disabled={loading}
          onClick={handleConfirm}
          className={classnames("ra-confirm", {
            [classes.confirmWarning]: confirmColor === "warning",
            [classes.confirmPrimary]: confirmColor === "primary"
          })}
          autoFocus
        >
          <ActionCheck className={classes.iconPaddingStyle} />
          {confirm}
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export default Confirm;

SaveWithConfirmation.tsx*

    import React, { useCallback, useState, Fragment } from "react";
import { useFormState } from "react-final-form";
import {
  SaveButton,
  Toolbar,
  useCreate,
  useRedirect,
  useNotify,
  Button
} from "react-admin";
import Confirm from "./Confirm";

const SaveWithConfirmButton = ({ resource, ...props }) => {
  const [create, { loading }] = useCreate(resource);
  const redirectTo = useRedirect();
  const notify = useNotify();
  const { basePath } = props;
  // get values from the form
  const formState = useFormState();
  const [open, setOpen] = useState(false);
  const handleDialogClick = e => {
    setOpen(true);
  };

  const handleDialogClose = e => {
    setOpen(false);
    e.stopPropagation();
  };

  const handleSave = useCallback(
    (values, redirect) => {
      // call dataProvider.create() manually
      // setOpen(true);
      create(
        {
          payload: { data: { ...values } }
        },
        {
          onSuccess: ({ data: newRecord }) => {
            notify("ra.notification.created", "info", {
              smart_count: 1
            });
            redirectTo(redirect, basePath, newRecord.id, newRecord);
          },
          onFailure: error => {
            notify(
              typeof error === "string"
                ? error
                : error.message || "ra.notification.http_error",
              "warning"
            );
            setOpen(false);
          }
        }
      );
    },
    [create, notify, redirectTo, basePath, formState]
  );

  return (
    <>
      <SaveButton {...props} onSave={handleDialogClick} />
      <Confirm
        isOpen={open}
        loading={loading}
        title="Please confirm"
        content="Are you sure you want to apply the changes ?"
        onConfirm={handleSave}
        onClose={handleDialogClose}
      />
    </>
  );
};

export default SaveWithConfirmButton;

用法


const DateCreateToolbar = props => (
  <Toolbar {...props}>
    <SaveWithConfirmButton resource="dates" />
  </Toolbar>
);
const DateCreate = props => {
  return (
    <Create {...props}>
      <SimpleForm toolbar={<DateCreateToolbar />} redirect="list">
        <DateTimeInput
          validate={required()}
          label="Start Date"
          source="startDate"
        />
        <DateTimeInput
          validate={required()}
          label="End Date"
          source="endDate"
        />
      </SimpleForm>
    </Create>
  );
};

export default DateCreate;

标签: reactjsmaterial-uireact-adminreact-final-form

解决方案


  <Toolbar {...props}>
    <SaveButton
      label="Save"
      redirect="edit"
      submitOnEnter={false}
      handleSubmitWithRedirect={
        () => {
          if(!window.confirm('Are you sure?'))
            return false;
          return props.handleSubmitWithRedirect();
        }
      }
    />
  </Toolbar>

推荐阅读