映射数据渲染多个 Material-UI 对话框组件

DJ2*_*DJ2 3 javascript reactjs material-ui

我正在表中显示用户列表。每行都有一个单元格,其中包含一个用于删除用户的按钮。单击删除按钮时,我将渲染一个 Material-UI<Dialog />组件以进行确认。

问题是地图导致渲染 3 个对话框,最后一个对话框位于顶部。因此,如果数组中有 3 个用户,则会呈现 3 个对话框,但您只能与第 3 个对话框交互(它会阻止其他 2 个对话框出现)。

这个问题与this 类似

有没有办法控制打开哪个对话框?

handleDeleteUser是一个发出请求的异步函数,因此我需要将id和传递links给该方法。

我这里有一个简化的codesandbox 。如果您尝试删除用户 1 或用户 2,您可以看到控制台中仅显示用户 3 的 ID 和链接。

const handleDeleteUser = (id, links) => {
  // this always prints the id and links for the last user in the table
  console.log("deleting user -->", id);
  console.log("user delete URL", links.self);
  setOpen(false);
};

<Table.Body>
  {userList && userList.length >= 1 ? (
    userList.map(
      ({ id, attributes, links, i }, index) => {
        return (
          <Table.Row key={index}>
            <Table.Cell textAlign="center">
              <Button
                circular
                icon
                size="mini"
                color="red"
                type="button"
                onClick={handleClickOpen}
              >
                <Icon name="delete" />
              </Button>
              <Dialog
                open={open}
                onClose={handleClose}
                aria-labelledby="alert-dialog-title"
                aria-describedby="alert-dialog-description"
              >
              <DialogTitle id="alert-dialog-title">
                {"Confirm User Delete"}
              </DialogTitle>
              <DialogContent>
                <DialogContentText id="alert-dialog-description">
                  {`Are you sure you want to delete this user?`}
                </DialogContentText>
              </DialogContent>
              <DialogActions>
                <MUIButton
                  type="button"
                  onClick={handleDeleteUser.bind(
                    this,
                    id,
                    links
                  )}
                  color="primary"
                >
                  Yes
                </MUIButton>
                <MUIButton
                  type="button"
                  onClick={handleClose}
                  color="primary"
                  autoFocus
                 >
                   Cancel
                </MUIButton>
              </DialogActions>
            </Dialog>
Run Code Online (Sandbox Code Playgroud)

IAM*_*STR 5

您遇到的问题是,当按下触发模式的按钮时,它会将状态打开设置为 true 并且所有对话框共享此状态

您要做的是将 Dialog 组件移动到另一个文件并从那里导入它,然后将单击处理程序和状态作为 props 传递。

这是我的解决方案

步骤1

将触发模式打开的按钮和对话框组件移动到不同的文件中

import React, { useState } from "react";

import { Button, Icon } from "semantic-ui-react";

import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";

import MUIButton from "@material-ui/core/Button";

const CustomDialog = (props) => {
  const [open, setOpen] = useState(false);

  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <>
      <Button
        circular
        icon
        size="mini"
        color="red"
        type="button"
        onClick={() => handleClickOpen()}
      >
        <Icon name="delete" />
      </Button>

      <Dialog
        open={open}
        onClose={handleClose}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
      >
        <DialogTitle id="alert-dialog-title">
          {"Confirm User Delete"}
        </DialogTitle>
        <DialogContent>
          <DialogContentText id="alert-dialog-description">
            {`Are you sure you want to delete this user: ${props.id}?`}
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <MUIButton
            type="button"
            onClick={() => {
              props.handleDeleteUser(props.id, props.links);
              setOpen(false);
            }}
            color="primary"
          >
            Yes
          </MUIButton>
          <MUIButton
            type="button"
            onClick={handleClose}
            color="primary"
            autoFocus
          >
            Cancel
          </MUIButton>
        </DialogActions>
      </Dialog>
    </>
  );
};
export default CustomDialog;
Run Code Online (Sandbox Code Playgroud)

第2步

我像这样重构了你的表格组件

                    <React.Fragment key={index}>
                        <Table.Row key={index}>
                          <Table.Cell textAlign="center">
                            <CustomDialog
                              id={id}
                              links={links}
                              handleDeleteUser={handleDeleteUser}
                            />
                          </Table.Cell>
                          <Table.Cell>{id}</Table.Cell>
                        </Table.Row>
                      </React.Fragment>
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我已经传递了idandlinkshandleDeleteUser作为 props ,通过这样做,你可以让你的对话框拥有自己的状态而不是共享状态,因此你没有得到你想要的结果

你可以在这里预览它codesandbox

提示

最好将每个组件放在不同的文件中,这样更干净,您可以轻松调试可能出现的问题