Javascript 映射数据渲染多个材质UI对话框组件
我正在表中显示用户列表。每行有一个单元格,其中包含一个用于删除用户的按钮。单击“删除”按钮时,我正在渲染一个要确认的文件 问题是映射导致渲染3个对话框,最后一个对话框位于顶部。因此,如果阵列中有3个用户,将呈现3个对话框,但您只能与第3个对话框交互(它会阻止其他2个用户查看) 这个问题类似于 有没有办法控制打开哪个对话框Javascript 映射数据渲染多个材质UI对话框组件,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我正在表中显示用户列表。每行有一个单元格,其中包含一个用于删除用户的按钮。单击“删除”按钮时,我正在渲染一个要确认的文件 问题是映射导致渲染3个对话框,最后一个对话框位于顶部。因此,如果阵列中有3个用户,将呈现3个对话框,但您只能与第3个对话框交互(它会阻止其他2个用户查看) 这个问题类似于 有没有办法控制打开哪个对话框 handleDeleteUser是一个发出请求的异步函数,因此我需要将id和链接传递到该方法 我有一个简化的。如果尝试删除用户1或用户2,您可以看到控制台中只显示用户3的id和
handleDeleteUser
是一个发出请求的异步函数,因此我需要将id
和链接传递到该方法
我有一个简化的。如果尝试删除用户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>
consthandledeletueser=(id,links)=>{
//这将始终打印表中最后一个用户的id和链接
log(“删除用户-->”,id);
log(“用户删除URL”,links.self);
setOpen(假);
};
{userList&&userList.length>=1(
userList.map(
({id,属性,链接,i},索引)=>{
返回(
{“确认用户删除”}
{`确实要删除此用户吗?`}
对
取消
您遇到的问题是,当按下触发模式的按钮时,它会将状态设置为“打开”,并且所有对话框都共享此信息
您要做的是将对话框组件移动到另一个文件中,然后从那里导入它,并将单击处理程序和状态作为道具传递
这是我的解决办法
第一步
将触发模式打开和对话框组件的按钮移动到其他文件中
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;
import React,{useState}来自“React”;
从“语义ui反应”导入{按钮,图标};
从“@material ui/core/Dialog”导入对话框;
从“@material ui/core/DialogActions”导入DialogActions;
从“@material ui/core/DialogContent”导入DialogContent;
从“@material ui/core/DialogContentText”导入DialogContentText;
从“@material ui/core/DialogTitle”导入DialogTitle;
从“@material ui/core/Button”导入MUIButton;
const CustomDialog=(道具)=>{
const[open,setOpen]=useState(false);
常量handleClickOpen=()=>{
setOpen(真);
};
常量handleClose=()=>{
setOpen(假);
};
返回(
handleClickOpen()}
>
{“确认用户删除”}
{`确实要删除此用户:${props.id}?`}
{
props.handleDeleteUser(props.id,props.links);
setOpen(假);
}}
color=“primary”
>
对
取消
);
};
导出默认自定义对话框;
步骤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>
{id}
正如您所见,我将id
和链接
和handleDeleteUser
作为道具传递,这样做会使对话框有自己的状态,而不是共享状态,因此您没有得到想要的结果
你可以在这里预览
提示
最好将每个组件放在不同的文件中,并使其方式更清晰,您可以轻松调试可能出现的问题为什么要在每个循环中呈现对话框?我认为,您需要定义一次。因为对话框的“打开”状态与每个用户相同,并且无论单击哪个用户都会触发。您可以尝试
const [ selectedUser,setSelectedUser ] = useState()
const [ open,setOpen ] = useState(false)
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);
};
return(
<>
<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 ${selectedUser.name} user?`}
</DialogContentText>
</DialogContent>
<DialogActions>
<MUIButton
type="button"
onClick={() => handleDeleteUser(selectedUser.id,selectedUser.links)}
color="primary"
>
Yes
</MUIButton>
<MUIButton
type="button"
onClick={handleClose}
color="primary"
autoFocus
>
Cancel
</MUIButton>
</DialogActions>
</Dialog>
{
users.map((user,index) => (
<TableRow style={{backgroundColor:'green'}} key={index}>
<TableCell style={{color:'#fff'}}>{user.name}</TableCell>
<Button onClick={() => {
selectedUser(user),
setOpen(true)
}} >Delete me!</Button>
</TableRow>
))
}
</>
)
const[selectedUser,setSelectedUser]=useState()
const[open,setOpen]=useState(false)
常量handleDeleteUser=(id,链接)=>{
//这将始终打印表中最后一个用户的id和链接
log(“删除用户-->”,id);
log(“用户删除URL”,links.self);
setOpen(假);
};
返回(
{“确认用户删除”}
{`您确定要删除${selectedUser.name}用户吗?`}
handleDeleteUser(selectedUser.id,selectedUser.links)}
color=“primary”
>
对
取消
{
users.map((用户,索引)=>(
{user.name}
{
selectedUser(用户),
setOpen(真)
}}>删除我!
))
}
)