typescript 从父项中的父项打开材质UI模式

hgc7kmma  于 2022-11-26  发布在  TypeScript
关注(0)|答案(1)|浏览(132)

我有一个表,上面有球队的名单;每行的最后一列打开一个菜单,我希望菜单项打开一个模态或对话框,这取决于菜单项。2我希望将表、菜单和模态作为单独的组件。3所以看起来像这样:
Teams.tsx

const testDataTeams = [
  { name: 'Cincinatti Bengals', owner: 'John Person', created: '11/11/11', members: 4 },
  { name: 'Los Angeles Rams', owner: 'John Person', created: '11/11/11', members: 3 },
  { name: 'The A-Team', owner: 'John Person', created: '11/11/11', members: 2 },
]

export default function Teams() {
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const [openModal, setOpen] = React.useState(null);
    const open = Boolean(anchorEl);
    const moreOptions = (event: React.MouseEvent<HTMLButtonElement>) => {
      setAnchorEl(event.currentTarget);
    };
    const handleClose = () => {
      setAnchorEl(null);
    };

    const clickModal = Boolean(openModal)
    const closeModal = () => {
      setOpen(null)
    };
  return (
    <TableContainer component={Paper}>
    <Table sx={{ display: { xs: 'none', md: 'table', lg: 'table' }, minWidth: 700 }} aria-label="customized table">
      <TableHead>
        <TableRow>
          <StyledTableCell>Name</StyledTableCell>
          <StyledTableCell align="right">Owner</StyledTableCell>
          <StyledTableCell align="right">Date&nbsp;Created</StyledTableCell>
          <StyledTableCell align="right">Members</StyledTableCell>
          <StyledTableCell align="right"></StyledTableCell>
        </TableRow>
      </TableHead>
      <TableBody>
        {testDataTeams.map((item) => (
          <StyledTableRow key={item.name}>
            <StyledTableCell component="th" scope="row">{item.name}</StyledTableCell>
            <StyledTableCell align="right">{item.owner}</StyledTableCell>
            <StyledTableCell align="right">{item.created}</StyledTableCell>
            <StyledTableCell align="right">{item.members}</StyledTableCell>
            <StyledTableCell align="right">
              <IconButton 
                id="basic-button"
                aria-controls={open ? 'basic-menu' : undefined}
                aria-haspopup="true"
                aria-expanded={open ? 'true' : undefined}
                onClick={moreOptions}>
                <MoreIcon />
              </IconButton>
              <Menu
                id="basic-menu"
                anchorEl={anchorEl}
                open={open}
                onClose={handleClose}
                MenuListProps={{
                  'aria-labelledby': 'basic-button',
                }}
              >
                <TeamMenu clickModal={clickModal} closeModal={closeModal} />
              </Menu>
            </StyledTableCell>
          </StyledTableRow>
        ))}
      </TableBody>
    </Table>
  </TableContainer>
  );
}

TeamMenu.tsx

export default function TeamMenu(clickModal, closeModal) {
    return (
        <div>
        <MenuItem>
          <ListItemIcon>
            <NotificationsIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Notification Settings</ListItemText>
        </MenuItem>
        <MenuItem onClick={closeModal}>
          <ListItemIcon>
            <EditIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Edit Team Info</ListItemText>
        </MenuItem>
        <TeamsModal open={clickModal} handleClose={closeModal} />
        <MenuItem>
          <ListItemIcon>
            <GroupIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Edit Members</ListItemText>
        </MenuItem>
        <MenuItem>
          <ListItemIcon>
            <DeleteIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Delete Team</ListItemText>
        </MenuItem>
        </div>
  );
}

TeamsModal.tsx

const TeamsModal = ({ open, handleClose }) => {
  return (
    <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-modal-title"
        aria-describedby="modal-modal-description"
      >
        <Box>
          <Typography id="modal-modal-title" variant="h6" component="h2">
            Text in a modal
          </Typography>
          <Typography id="modal-modal-description" sx={{ mt: 2 }}>
            Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
          </Typography>
        </Box>
      </Modal>
  )
}

export default TeamsModal;

我可以让道具传递到团队菜单,但是我在下一层遇到了麻烦,我担心我的代码太复杂了。执行这个的最好方法是什么?

jogvjijk

jogvjijk1#

您可以像在这里所做的那样,将回调函数传递给TeamsMenu组件,但它看起来不像是在Teams组件中返回实际的TeamsModal组件。
您需要在Teams组件中包含TeamsModal,如下所示:

const testDataTeams = [
  { name: 'Cincinatti Bengals', owner: 'John Person', created: '11/11/11', members: 4 },
  { name: 'Los Angeles Rams', owner: 'John Person', created: '11/11/11', members: 3 },
  { name: 'The A-Team', owner: 'John Person', created: '11/11/11', members: 2 },
]

export default function Teams() {
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const [openModal, setOpen] = React.useState<boolean>(false);
    const open = Boolean(anchorEl);
    const moreOptions = (event: React.MouseEvent<HTMLButtonElement>) => {
      setAnchorEl(event.currentTarget);
    };
    const handleClose = () => {
      setAnchorEl(null);
    };

    const clickModal = () => setOpen(true);
    const closeModal = () => setOpen(false);
  return (
<>
    <TableContainer component={Paper}>
    <Table sx={{ display: { xs: 'none', md: 'table', lg: 'table' }, minWidth: 700 }} aria-label="customized table">
      <TableHead>
        <TableRow>
          <StyledTableCell>Name</StyledTableCell>
          <StyledTableCell align="right">Owner</StyledTableCell>
          <StyledTableCell align="right">Date&nbsp;Created</StyledTableCell>
          <StyledTableCell align="right">Members</StyledTableCell>
          <StyledTableCell align="right"></StyledTableCell>
        </TableRow>
      </TableHead>
      <TableBody>
        {testDataTeams.map((item) => (
          <StyledTableRow key={item.name}>
            <StyledTableCell component="th" scope="row">{item.name}</StyledTableCell>
            <StyledTableCell align="right">{item.owner}</StyledTableCell>
            <StyledTableCell align="right">{item.created}</StyledTableCell>
            <StyledTableCell align="right">{item.members}</StyledTableCell>
            <StyledTableCell align="right">
              <IconButton 
                id="basic-button"
                aria-controls={open ? 'basic-menu' : undefined}
                aria-haspopup="true"
                aria-expanded={open ? 'true' : undefined}
                onClick={moreOptions}>
                <MoreIcon />
              </IconButton>
              <Menu
                id="basic-menu"
                anchorEl={anchorEl}
                open={open}
                onClose={handleClose}
                MenuListProps={{
                  'aria-labelledby': 'basic-button',
                }}
              >
                <TeamMenu clickModal={clickModal} closeModal={closeModal} />
              </Menu>
            </StyledTableCell>
          </StyledTableRow>
        ))}
      </TableBody>
    </Table>
  </TableContainer>
 {openModal && (
  <TeamsModal open={openModal} handleClose={() => setOpen(false)} />
)}
</>
  );
}

注意,我将open的状态类型定义为boolean而不是null。
这确保了当openModal状态设置为true时,模态将打开。
此外,如果您正在使用Typescript,我建议您为组件和道具定义类型,以确保您不会犯愚蠢的错误,并具有甜蜜的自动完成功能。

相关问题