Reactjs 如何处理多个popover(材质ui)

Reactjs 如何处理多个popover(材质ui),reactjs,material-ui,tsx,Reactjs,Material Ui,Tsx,我试图在一个组件中使用多个popover。例如,在下面的代码中,我有两个弹出框,但是当单击这两个按钮中的任何一个时,两个弹出框都被打开。我们如何处理onclick以打开相应的popover const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); const handleClick = (event: React.MouseEvent<HTMLButtonElement>)

我试图在一个组件中使用多个popover。例如,在下面的代码中,我有两个弹出框,但是当单击这两个按钮中的任何一个时,两个弹出框都被打开。我们如何处理onclick以打开相应的popover

const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
        setAnchorEl(event.currentTarget);
    };

    const handleClose = () => {
    setAnchorEl(null);
    };

<Tabs variant="fullWidth" value={value} onChange={onNavChange} indicatorColor="transparent">
                        <Tab label="Menu 1" className={classes.navTab} component={Link} to="./Menu1"></Tab>
                        <Tab label="Menu 2" onClick={handleClick} aria-describedby="menu2Popover" aria-haspopup="true"></Tab>
                        <Tab label="Menu 3" component={Link} to="./Menu3"></Tab>
                        <Tab label="Menu 4"onClick={handleClick} aria-describedby="menu4Popover" aria-haspopup="true"></Tab>
                    </Tabs>
                    <Popover 
                        id="menu2Popover" open={Boolean(anchorEl)} onClose={handleClose}
                        anchorEl = {anchorEl}
                        anchorOrigin={{
                            vertical: 'top',
                            horizontal: 'left',
                        }}
                        transformOrigin={{
                            vertical: 'bottom',
                            horizontal: 'left',
                        }}>
                        <MenuList>
                            <MenuItem>Submenu 1</MenuItem>
                            <MenuItem>Submenu 2</MenuItem>
                        </MenuList>
                    </Popover>
                    <Popover 
                        id="menu4Popover" open={Boolean(anchorEl)} onClose={handleClose}
                        anchorEl = {anchorEl}
                        anchorOrigin={{
                            vertical: 'top',
                            horizontal: 'left',
                        }}
                        transformOrigin={{
                            vertical: 'bottom',
                            horizontal: 'left',
                        }}>
                        <MenuList>
                            <MenuItem>Submenu 3</MenuItem>
                            <MenuItem>Submenu 4</MenuItem>
                        </MenuList>
                    </Popover>
const[anchorEl,setAnchorEl]=React.useState(null);
常量handleClick=(事件:React.MouseEvent)=>{
Setancorel(事件当前目标);
};
常量handleClose=()=>{
setAnchorEl(空);
};
子菜单1
子菜单2
子菜单3
子菜单4

您需要为每个Popover使用不同的
anchorEl

import * as React from "react";
import { render } from "react-dom";
import { MenuList, MenuItem, Popover, Tabs, Tab } from "@material-ui/core";

import "./styles.css";

interface CustomMenuItem {
  anchorEl: null | HTMLElement;
  child: any;
}

function Popover1() {
  return (
    <MenuList>
      <MenuItem>Submenu 1</MenuItem>
      <MenuItem>Submenu 2</MenuItem>
    </MenuList>
  );
}

function Popover2() {
  return (
    <MenuList>
      <MenuItem>Submenu 3</MenuItem>
      <MenuItem>Submenu 4</MenuItem>
    </MenuList>
  );
}

function App() {
  const [popover1, setPopover1] = React.useState<CustomMenuItem>({
    anchorEl: null,
    child: <Popover1 />
  });
  const [popover2, setPopover2] = React.useState<CustomMenuItem>({
    anchorEl: null,
    child: <Popover2 />
  });

  return (
    <div className="App">
      <Tabs variant="fullWidth" indicatorColor="transparent">
        <Tab label="Menu 1" />
        <Tab
          value="Tab2"
          label="Menu 2"
          onClick={(event: React.MouseEvent<HTMLButtonElement>) =>
            setPopover1({ ...popover1, anchorEl: event.currentTarget })
          }
          aria-describedby="menu2Popover"
          aria-haspopup="true"
        />
        <Tab label="Menu 3" />
        <Tab
          label="Menu 4"
          onClick={(event: React.MouseEvent<HTMLButtonElement>) =>
            setPopover2({ ...popover2, anchorEl: event.currentTarget })
          }
          aria-describedby="menu4Popover"
          aria-haspopup="true"
        />
      </Tabs>

      <Popover
        id="menu2Popover"
        open={Boolean(popover1.anchorEl)}
        onClose={() => setPopover1({ ...popover1, anchorEl: null })}
        anchorEl={popover1.anchorEl}
        anchorOrigin={{
          vertical: "top",
          horizontal: "left"
        }}
        transformOrigin={{
          vertical: "bottom",
          horizontal: "left"
        }}
      >
        {popover1.child}
      </Popover>
      <Popover
        id="menu4Popover"
        open={Boolean(popover2.anchorEl)}
        onClose={() => setPopover2({ ...popover2, anchorEl: null })}
        anchorEl={popover2.anchorEl}
        anchorOrigin={{
          vertical: "top",
          horizontal: "left"
        }}
        transformOrigin={{
          vertical: "bottom",
          horizontal: "left"
        }}
      >
        {popover2.child}
      </Popover>
    </div>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);
import*as React from“React”;
从“react dom”导入{render};
从“@material ui/core”导入{MenuList,MenuItem,Popover,Tabs,Tab}”;
导入“/styles.css”;
接口CustomMenuItem{
主播:null | HTMLElement;
儿童:任何;
}
函数Popover1(){
返回(
子菜单1
子菜单2
);
}
函数Popover2(){
返回(
子菜单3
子菜单4
);
}
函数App(){
常量[popover1,setPopover1]=React.useState({
主持人:空,
儿童:
});
常量[popover2,setPopover2]=React.useState({
主持人:空,
儿童:
});
返回(
setPopover1({…popover1,主播:event.currentTarget})
}
aria descripeby=“menu2Popover”
aria haspoop=“true”
/>
setPopover2({…popover2,主播:event.currentTarget})
}
aria descripeby=“menu4pover”
aria haspoop=“true”
/>
setPopover1({…popover1,主播:null})
anchorEl={popover1.anchorEl}
锚定素={{
垂直:“顶部”,
水平:“左”
}}
变形金刚={{
垂直:“底部”,
水平:“左”
}}
>
{popover1.child}
setPopover2({…popover2,主播:null})}
anchorEl={popover2.anchorEl}
锚定素={{
垂直:“顶部”,
水平:“左”
}}
变形金刚={{
垂直:“底部”,
水平:“左”
}}
>
{popover2.child}
);
}
const rootElement=document.getElementById(“根”);

render(.如果您还有任何问题,请告诉我,我可以更新我的答案。

另一个带有一个Popover的示例

import React from "react";
import { withStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Popover from "@material-ui/core/Popover";
import MenuList from "@material-ui/core/MenuList";
import MenuItem from "@material-ui/core/MenuItem";

const styles = theme => ({
  root: {
    flexGrow: 1,
    backgroundColor: theme.palette.background.paper,
    textTransform: "none"
  }
});

class SimpleTabs extends React.Component {
  state = {
    value: 0,
    anchorEl: null,
    popno: -1
  };

  handlePopoverClose = () => {
    this.setState({ anchorEl: null, popno: -1 });
  };

  handleClick = (e, _popno) => {
    this.setState({ anchorEl: e.currentTarget, popno: _popno });
  };

  handleChange = (event, value) => {
    this.setState({ value });
  };

  render() {
    const { classes } = this.props;
    const { value } = this.state;

    return (
      <div className={classes.root}>
        <AppBar position="static">
          <Tabs value={value} onChange={this.handleChange}>
            <Tab label="Tab 1" onClick={e => this.handleClick(e, 1)} />
            <Tab label="Tab 2" onClick={e => this.handleClick(e, 2)} />
            <Tab label="Tab 3" onClick={e => this.handleClick(e, 3)} />
          </Tabs>
          <Popover
            id="menu2Popover"
            open={this.state.anchorEl !== null}
            onClose={this.handlePopoverClose}
            anchorEl={this.state.anchorEl}
          >
            {this.state.popno === 1 && (
              <MenuList>
                <MenuItem>Tab 1 - Submenu 1</MenuItem>
                <MenuItem>Tab 1 - Submenu 2</MenuItem>
              </MenuList>
            )}
            {this.state.popno === 2 && (
              <MenuList>
                <MenuItem>Tab 2 - Submenu 1</MenuItem>
                <MenuItem>Tab 2 - Submenu 2</MenuItem>
              </MenuList>
            )}
            {this.state.popno === 3 && (
              <MenuList>
                <MenuItem>Tab 3 - Submenu 1</MenuItem>
                <MenuItem>Tab 3 - Submenu 2</MenuItem>
              </MenuList>
            )}
          </Popover>
        </AppBar>
      </div>
    );
  }
}

export default withStyles(styles)(SimpleTabs);
从“React”导入React;
从“@material ui/core/styles”导入{withStyles}”;
从“@material ui/core/AppBar”导入AppBar;
从“@material ui/core/Tabs”导入选项卡;
从“@material ui/core/Tab”导入选项卡;
从“@material ui/core/Popover”导入Popover;
从“@material ui/core/MenuList”导入菜单列表;
从“@material ui/core/MenuItem”导入菜单项;
常量样式=主题=>({
根目录:{
flexGrow:1,
背景色:theme.palete.background.paper,
textTransform:“无”
}
});
类SimpleTabs扩展了React.Component{
状态={
值:0,
主持人:空,
波普诺-1
};
handlePopoverClose=()=>{
this.setState({ancorel:null,popno:-1});
};
handleClick=(e,_popno)=>{
this.setState({ancorel:e.currentTarget,popno:_popno});
};
handleChange=(事件、值)=>{
this.setState({value});
};
render(){
const{classes}=this.props;
const{value}=this.state;
返回(

嘿,谢谢!它成功了。还提供了有关如何处理动态添加的菜单及其子菜单弹出窗口的详细信息?@shiva我使代码更灵活,更容易创建不同的子菜单。如果您的菜单、子菜单始终看起来相同,则可以将其重构为自己的组件。如果它现在适用于您,您能接受我的回答吗?我想我从json获取菜单和子菜单,因此如果稍后添加子菜单,组件应该可以工作。如果您接受我的答案(单击答案右侧的绿色勾号),我可以查看它