根据数组内容显示项目

show items based on array content

我有一个 header 菜单,其中有子菜单项。例如在下面,第一个项目单独有子菜单。我必须仅在 header 菜单上显示悬停子菜单,因为 submenu.But 我正在使用 tailwindcss 获取悬停所有 header menu.I 的子菜单这个和下面是代码片段。

headerdata.json

{  
    "headerData": [
        {"text":"Home Applicances", "url":"homeappli","submenu":[
            {
            "submenuText":"Television",
            "url":""
        }, 
        {
            "submenuText":"Fridge",
            "url":""
        }, 
        {
            "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;

所以你这里有两个错误:

  1. 总是添加了悬停事件
  2. 你总是显示相同的子菜单

这是一个固定的例子: 还有 CodeSandbox

import React, { useState } from "react";
import "./styles.css";

const data = {
  headerData: [
    {
      text: "Home Applicances",
      url: "homeappli",
      submenu: [
        {
          submenuText: "Television",
          url: ""
        },
        {
          submenuText: "Fridge",
          url: ""
        },
        {
          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",
          "url": ""
        },
        {
          "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);