问题描述
我有一个带有子菜单项的标题菜单。例如,在下面的第一项中就有单独的子菜单。我只在标题菜单上显示了子菜单,但是我将鼠标悬停在所有标题菜单上,下面是代码片段。
headerdata.json
{
"headerData": [
{"text":"Home Applicances","url":"homeappli","submenu":[
{
"submenuText":"Television","url":""
},{
"submenuText":"Fridge",{
"submenuText":"Washing Machine","url":""
}
]},{"text":"Mobiles & Accessories","url":"mobile"},{"text":"Discount Combos","url":"disc"},{"text":"Offers","url":"offers"}
]
}
和JS:
import React,{ useState } from "react";
// import './Header.styles';
import logo from "../../images/logo-dark.png";
import FavoriteBorderIcon from "@material-ui/icons/FavoriteBorder";
import ShoppingCartIcon from "@material-ui/icons/ShoppingCart";
import SearchIcon from "@material-ui/icons/Search";
import Avatar from "@material-ui/core/Avatar";
import LoginModal from "../Modal/LoginModal";
import headerData from "../../data/headerData.json";
function Header() {
const [openSearch,setOpensearch] = useState(false);
const [isUserLogged,setIsUserLogged] = useState(false);
const [showSubmenu,setShowSubmenu] = useState(false);
const handleSearch = () => {
setOpensearch(!openSearch);
};
const handleLogin = () => {
// Checking whether used loggedin using local storage logic
setIsUserLogged(true);
// return <LoginModal />
};
const closeModal = () => {
setIsUserLogged(false);
};
return (
<div className="fixed md:px-8 px-8 w-full z-10 bg-white shadow-md">
<div className="flex lg:justify-around md:my-3 md:flex-row sm:flex-row ">
<div className="flex justify-center items-center w-full">
<img src={logo} className="h-30 md:h-30 " alt="Ansar_logo" />
</div>
<div className="flex text-lg cursor-pointer h-10" onClick={handleLogin}>
<div className="px-2 whitespace-no-wrap flex items-center">
Sign In
</div>
<Avatar />
</div>
{isUserLogged && <LoginModal handleClose={closeModal} />}
</div>
<div className="flex lg:justify-around md:mb-6 md:flex-row sm:flex-row h-4">
<div className="flex justify-center items-center w-4/5">
{headerData?.headerData?.map((data) => {
return (
<div
onMouseEnter={() => setShowSubmenu(true)}
onMouseLeave={() => setShowSubmenu(false)}
className="px-5 cursor-pointer font-medium hover:text-green-900 hover:border-1 hover:border-solid hover:border-green-900 uppercase ">
{data.text}
</div>
);
})}
</div>
{showSubmenu && <div>
{headerData?.headerData[0].submenu.map((data) => {
return (
<li className="px-5 py-2
cursor-pointer relative font-medium bg-red-800 hover:text-green-900 uppercase list-none">
{data.submenuText}
</li>
);
})}
</div>
}
<div className="flex justify-end w-1/5">
<div className="pr-2 flex">
{openSearch && (
<input
type="search"
className=" w-auto border-b-2 px-8 py-4 -mt-3 border-black outline-none"
placeholder="Search product...."
/>
)}
<SearchIcon onClick={handleSearch} className="cursor-pointer" />
</div>
<div className="pr-2 flex flex-col place-items-center ">
<FavoriteBorderIcon className="cursor-pointer" />
</div>
<div className="flex flex-col place-items-center">
<ShoppingCartIcon className="cursor-pointer" />
</div>
</div>
</div>
</div>
);
}
export default Header;
解决方法
所以这里有两个错误:
- 您总是添加了悬停事件
- 您始终显示相同的子菜单
这是一个固定的示例: 还有CodeSandbox
import React,{ useState } from "react";
import "./styles.css";
const data = {
headerData: [
{
text: "Home Applicances",url: "homeappli",submenu: [
{
submenuText: "Television",url: ""
},{
submenuText: "Fridge",{
submenuText: "Washing Machine",url: ""
}
]
},{ text: "Mobiles & Accessories",url: "mobile" },{ text: "Discount Combos",url: "disc" },{ text: "Offers",url: "offers" }
]
};
export default function App() {
const [currentSubment,setCurrentSubmenu] = useState(-1);
return (
<div className="flex lg:justify-around md:mb-6 md:flex-row sm:flex-row h-4">
<div className="flex justify-center items-center w-4/5">
{data.headerData.map((data,index) => {
if (data.submenu) {
return (
<div
onMouseEnter={() => setCurrentSubmenu(index)}
onMouseLeave={() => setCurrentSubmenu(-1)}
className="px-5 cursor-pointer font-medium hover:text-green-900 hover:border-1 hover:border-solid hover:border-green-900 uppercase "
>
{data.text}
</div>
);
}
return (
<div className="px-5 cursor-pointer font-medium hover:text-green-900 hover:border-1 hover:border-solid hover:border-green-900 uppercase ">
{data.text}
</div>
);
})}
</div>
{currentSubment > -1 && (
<div>
{data.headerData[currentSubment].submenu.map((data) => {
return (
<li
className="px-5 py-2
cursor-pointer relative font-medium bg-red-800 hover:text-green-900 uppercase list-none"
>
{data.submenuText}
</li>
);
})}
</div>
)}
</div>
);
}
,
您不是有条件地设置onMouseOver回调。相反,您设置的状态是对每个菜单项使用相同的子菜单。
以下是该修复程序的简化版本:
json文件:
{
"navbar": [
{
"text": "Home Applicances","url": "homeappli","submenu": [
{
"submenuText": "Television","url": ""
},{
"submenuText": "Fridge",{
"submenuText": "Washing Machine","url": ""
}
]
},{ "text": "Mobiles & Accessories","url": "mobile" },{ "text": "Discount Combos","url": "disc" },{ "text": "Offers","url": "offers" }
]
}
JavaScript文件(简体)
import React,{ useState } from "react";
import ReactDOM from "react-dom";
import headerData from "./headerData.json";
import "./styles.css";
function App() {
const [menuIndex,setMenuIndex] = useState(-1);
return (
<div id="navbarHolder">
{headerData.navbar.map((item,index) => {
return (
<div
key={index}
onMouseOver={
item.hasOwnProperty("submenu")
? () => setMenuIndex(index)
: () => setMenuIndex(-1)
}
>
{item.text}
</div>
);
})}
{menuIndex > -1 && (
<div>
{headerData.navbar[menuIndex].submenu.map((item) => {
return <li>{item.submenuText}</li>;
})}
</div>
)}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />,rootElement);