在 React 中打开另一个菜单时如何自动关闭一个菜单?
Posted
技术标签:
【中文标题】在 React 中打开另一个菜单时如何自动关闭一个菜单?【英文标题】:How to automaically close one menu when the other one is opened in React? 【发布时间】:2022-01-03 16:33:26 【问题描述】:我正在工作的地方我想在其他菜单打开时自动折叠菜单。现在我已经尝试过单独使用 useState 并传递值,但它不起作用。我正在与你分享之前和之后的代码。
在 Dashboard.jsx 中,我正在映射菜单并将其作为道具传递给 MenuCards.jsx,现在如果单击 A 菜单因此是可扩展的,它会再次传递给 getExpandableMenu 并扩展菜单。 我想要的最终目标是打开一个菜单,如果单击另一个菜单,则首先关闭第一个菜单。
代码前 -
// Dashboard.tsx
setMenuList([
title: "Thermal Comfort",
icon: thermal,
decorator: new ManekinDecorator(IModelApp.viewManager.selectedView!),
tooltip: "Thermal Comfort",
,
title: "Surface Plots",
icon: surfacePlot,
decorator: null,
tooltip: "Surface Plots",
,
title: "Contour Plots",
icon: contour,
decorator: null,
tooltip: "Contour Plots",
,
title: "Comfort Cloud",
icon: comfortCloud,
decorator: new ComfortDecorator(),
tooltip: "Comfort Cloud",
,
title: "Flowlines",
icon: flowline,
//decorator: getFlowLineDecorator(),
decorator: null,
tooltip: "FlowLines",
,
]);
else
setMenuList([]);
setIsDropDownVisibal(false);
, [viewPort]);
<div className="menu">
<div style= overflowY: "scroll", width: "inherit" >
menuList.map((menu) => (
<MenuCard
menu=menu.title
icon=menu.icon
decorator=menu.decorator
tooltip=menu.tooltip
/>
))
</div>
</div>
// MenuCard.tsx
const MenuCard = (props: any) =>
const [toggle, setToggle] = React.useState(true);
const [expandOption, setExpandOption] = React.useState(false);
const onClick = () =>
if (props.decorator !== null)
if (toggle)
IModelApp.viewManager.decorators.forEach((decorator) =>
IModelApp.viewManager.dropDecorator(decorator);
);
IModelApp.viewManager.addDecorator(props.decorator);
else IModelApp.viewManager.dropDecorator(props.decorator);
setToggle(!toggle);
setExpandOption(!expandOption);
;
const menu, icon, tooltip = props;
return (
<div>
<div className="mainMenu" onClick=onClick>
<div className="icon">
<img src=icon className="menuIcon" />
</div>
<div className="menuTitle">
<p className="title">menu</p>
</div>
<InfoTooltip tooltipText=tooltip />
</div>
expandOption && (
<GetExpandedMenu menuName=menu decorator=props.decorator />
)
</div>
);
;
export default MenuCard;
// GetExpandedMenu.tsx
export default function GetExpandedMenu(props:any)
const menuName = props
const surfacePlotManager= new SurfacePlotManager()
const contourPlotManager=new ContourPlotManager();
switch(menuName)
case 'Surface Plots':
return <SurfacePlot plotManager=surfacePlotManager/>
case 'Thermal Comfort':
return <ThermalComfortMenu decorator=props.decorator/>
case 'Flowlines':
return <FlowLines />
case "Contour Plots":
return <ContourPlot plotManager=contourPlotManager/>;
case 'Comfort Cloud':
return <ComfortCloud/>
default:
return <p>expanded options</p>;
这是我尝试做但失败的事情。
// MenuCard.tsx
// tried making separate useState for every menu
/* eslint-disable eqeqeq */
import React from "react";
import "./MenuCard.scss";
const MenuCard = (props: any) =>
const [toggle, setToggle] = React.useState(true);
const [expandOption, setExpandOption] = React.useState(false);
const [ThermalExpandOption, setThermalExpandOption] = React.useState(false);
const [SurfaceExpandOption, setSurfaceExpandOption] = React.useState(false);
const [ContourExpandOption, setContourExpandOption] = React.useState(false);
const [CloudExpandOption, setCloudExpandOption] = React.useState(false);
const [FlowlinesExpandOption, setFlowlinesExpandOption] = React.useState(false);
const onClick = () =>
console.log("Menu clicked is", props.id);
if (props.id == 0)
setThermalExpandOption(!ThermalExpandOption);
setSurfaceExpandOption(false);
setContourExpandOption(false);
setCloudExpandOption(false);
setFlowlinesExpandOption(false);
else if (props.id == 1)
setThermalExpandOption(false);
setSurfaceExpandOption(!SurfaceExpandOption);
setContourExpandOption(false);
setCloudExpandOption(false);
setFlowlinesExpandOption(false);
else if (props.id == 2)
setThermalExpandOption(false);
setSurfaceExpandOption(false);
setContourExpandOption(!CloudExpandOption);
setCloudExpandOption(false);
setFlowlinesExpandOption(false);
else if (props.id == 3)
setThermalExpandOption(false);
setSurfaceExpandOption(false);
setContourExpandOption(false);
setCloudExpandOption(!CloudExpandOption);
setFlowlinesExpandOption(false);
if (props.id == 4)
setThermalExpandOption(false);
setSurfaceExpandOption(false);
setContourExpandOption(false);
setCloudExpandOption(false);
setFlowlinesExpandOption(!FlowlinesExpandOption);
if (props.decorator !== null)
if (toggle)
IModelApp.viewManager.decorators.forEach((decorator) =>
IModelApp.viewManager.dropDecorator(decorator);
);
IModelApp.viewManager.addDecorator(props.decorator);
else IModelApp.viewManager.dropDecorator(props.decorator);
setToggle(!toggle);
setExpandOption(!expandOption);
;
const menu, icon, tooltip = props;
return (
<div>
<div className="mainMenu" onClick=onClick>
<div className="icon">
<img src=icon className="menuIcon" />
</div>
<div className="menuTitle">
<p className="title">menu</p>
</div>
<InfoTooltip tooltipText=tooltip />
</div>
ThermalExpandOption && (
<GetExpandedMenu menuName=menu decorator=props.decorator />
)
SurfaceExpandOption && (
<GetExpandedMenu menuName=menu decorator=props.decorator />
)
ContourExpandOption && (
<GetExpandedMenu menuName=menu decorator=props.decorator />
)
CloudExpandOption && (
<GetExpandedMenu menuName=menu decorator=props.decorator />
)
FlowlinesExpandOption && (
<GetExpandedMenu menuName=menu decorator=props.decorator />
)
</div>
);
;
export default MenuCard;
【问题讨论】:
看看***.com/a/43742307/6449750 为什么这个问题的标签是react-native
?
【参考方案1】:
提升状态。
如果您的项目的状态取决于它旁边的菜单项的状态,您可以将两者都重构为取决于“菜单”容器中的状态。类似于“openedItem”状态。
您可以在此处的 React 文档中找到详细说明: https://reactjs.org/docs/lifting-state-up.html , 举例。
【讨论】:
以上是关于在 React 中打开另一个菜单时如何自动关闭一个菜单?的主要内容,如果未能解决你的问题,请参考以下文章