【问题标题】:show items based on array content根据数组内容显示项目
【发布时间】:2021-01-02 16:02:48
【问题描述】:

我有一个标题菜单,其中包含子菜单项。例如在下面的第一项单独有子菜单。我只在作为子菜单的标题菜单上显示子菜单。但是我在悬停所有标题菜单时得到子菜单。我为此使用tailwindcss,下面是代码sn-p。

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;

【问题讨论】:

  • 请贴出整个JS文件。
  • 已更新完整的头 js 文件。

标签: javascript react-hooks tailwind-css


【解决方案1】:

所以你这里有两个错误:

  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>
  );
}

【讨论】:

  • 明白了。谢谢 :)
【解决方案2】:

您没有有条件地设置 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);

【讨论】:

  • 是的。明白了。谢谢 :)
猜你喜欢
  • 1970-01-01
  • 2015-08-20
  • 2018-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多