reactjs React组件未在MUI MenuItem onClick事件上呈现

lf3rwulv  于 2023-01-12  发布在  React
关注(0)|答案(1)|浏览(157)

我有一个简单的muiMenu,其中一个MenuItem应该呈现另一个React组件,问题是我的Menu呈现在另一个文件中,其中定义了closehandleClick函数。
问题:组件在单击MenuItem时不呈现。似乎是因为App组件中的setAnchor(null);总是将锚设置为null。这是否意味着我需要使用不同的anchor?如果是,如何使用?
菜单组件代码如下:

interface Props {
  handler: Handler;
  anchor: HTMLButtonElement | null;
  onClose: () => void;
}

const AddDataMenu = ({ handler,anchor, onClose }: Props) => {
  const renderDataPopOver = () => {
    console.log('this is clicked'); <<<<<<<<<< I can see this function is accessed 
    <AddDataPopover handler={handler} anchor={anchor} onClose={onClose} />;
  };

  return (
    <div>
      <Menu
        anchorEl={anchor}
        open={Boolean(anchor)}
        onClose={onClose}
        sx={{ width: 320, maxWidth: '100%' }}
      >
        <MenuItem onClick={renderDataPopOver}>
          <ListItemIcon>
            <DataIcon />
          </ListItemIcon>
          <Typography>item 1</Typography>
        </MenuItem>
      </Menu>
    </div>
  );
};

export default AddDataMenu;

这是呈现我的菜单的主要组件。

const App = ({ scope }) => {
  const ref = useRef<HTMLButtonElement>(null);

  const [anchor, setAnchor] = useState<HTMLButtonElement | null>(null);
  const [handler, setHandler] = useState<Handler>();

 

  const close = () => {          <<<<<<< this is accessed before MenuItem click
    setAnchor(null);
  };

  const handleClick = () => {    <<<<<<< this is accessed before MenuItem click
    setAnchor(ref.current);
  };

  return showAdd && handler ? (
    <MessageContainer
      message={'test'}
      actions={
        <Box ml={1}>
          <Button ref={ref} color="primary" variant="contained" onClick={handleClick}>
            {t('Visualization.chart-initial-states.AddColumns')}
          </Button>
          <AddDataMenu handler={handler} anchor={anchor} onClose={close} />
        </Box>
      }
    />
  ) : (
    <DisplayError />
  );
};
export default App;
34gzjxbg

34gzjxbg1#

假设目标是在点击MenuItem时呈现Menu旁边的次要Popover,也许组件确实需要将触发它作为anchorEl的任何MenuItem分配给所呈现的Popover
基本的现场示例:stackblitz(为了简单起见,这个例子和下面的例子省略了原始代码中的Menu之外的所有内容)。
AddDataMenu中,将AddDataPopover添加到输出中,其初始值anchorEl为空,这样它就不会立即呈现。匹配的anchorEl可以在handleOpen事件中赋值。
这里使用ref数组来引用多个MenuItem,但这是一种可选方法。

const AddDataMenu = ({ anchor, onClose }) => {
  const [itemAnchor, setItemAnchor] = useState(null);
  const itemRef = useRef([]);
  const handleClose = () => {
    setItemAnchor(null);
  };
  const handleOpen = (index) => {
    setItemAnchor(itemRef.current[index]);
  };
  return (
    <>
      <Menu
        anchorEl={anchor}
        open={Boolean(anchor)}
        onClose={onClose}
        sx={{
          width: 320,
          maxWidth: '100%',
        }}
      >
        {[1, 2, 3].map((item, index) => (
          <MenuItem
            ref={(node) => (itemRef.current[index] = node)}
            key={index}
            onClick={() => handleOpen(index)}
            sx={{ p: 2 }}
          >
            <ListItemIcon>
              <DataIcon />
            </ListItemIcon>
            <Typography>{`item ${item}`}</Typography>
          </MenuItem>
        ))}
      </Menu>
      <AddDataPopover anchor={itemAnchor} onClose={handleClose} />
    </>
  );
};

AddDataPopover中,将anchorEl连接到Popover,并在活动MenuItem旁边设置要呈现的组件的样式。

const AddDataPopover = ({ anchor, onClose }) => {
  return (
    <Popover
      id={'my-popover'}
      open={Boolean(anchor)}
      anchorEl={anchor}
      onClose={onClose}
      anchorOrigin={{
        vertical: 'center',
        horizontal: 'right',
      }}
      transformOrigin={{
        vertical: 'center',
        horizontal: 'left',
      }}
    >
      <Typography sx={{ p: 2 }}>The content of Data Popover.</Typography>
    </Popover>
  );
};

相关问题