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)
您遇到的问题是,当按下触发模式的按钮时,它会将状态打开设置为 true 并且所有对话框共享此状态
您要做的是将 Dialog 组件移动到另一个文件并从那里导入它,然后将单击处理程序和状态作为 props 传递。
这是我的解决方案
将触发模式打开的按钮和对话框组件移动到不同的文件中
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)
我像这样重构了你的表格组件
<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)
正如你所看到的,我已经传递了idandlinks和handleDeleteUser作为 props ,通过这样做,你可以让你的对话框拥有自己的状态而不是共享状态,因此你没有得到你想要的结果
你可以在这里预览它codesandbox
最好将每个组件放在不同的文件中,这样更干净,您可以轻松调试可能出现的问题