You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中实现单张图片hover时仅显示对应文本的解决方案

问题原因

你当前使用了一个全局的isHovering状态变量,所有技术卡片都依赖这个状态判断是否显示文本。只要任意一张卡片触发hover事件,全局状态就会变为true,导致所有卡片的文本同时显示。

快速修复方案

将单个布尔值状态改为存储当前hover的卡片标识(比如技术名称),只有当标识匹配时才显示对应文本:

const Experience = () => {
  // 用状态存储当前hover的技术标识,初始为null
  const [hoveredItem, setHoveredItem] = useState(null);

  return (
    <div
      name="experience"
      className="w-full h-screen bg-[#0a192f] text-gray-300"
    >
      <div className="max-w-[1000px] mx-auto flex flex-col justify-center w-full h-full">
        <div>
          <p className="text-4xl font-bold inline border-b-4 border-purple-800">
            Experience
          </p>
          <p className="py-4">Technologies I have worked with</p>
        </div>
        <div className="w-full grid grid-cols-2 sm:grid-cols-4 gap-4 text-center py-8">
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              onMouseOver={() => setHoveredItem('css')}
              onMouseOut={() => setHoveredItem(null)}
              className="w-20 mx-auto"
              src={CssLogo}
              alt="Css Logo"
            />
            {hoveredItem === 'css' ? <p className="font-bold">CSS</p> : ""}
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              onMouseOver={() => setHoveredItem('html')}
              onMouseOut={() => setHoveredItem(null)}
              className="w-20 mx-auto"
              src={HtmlLogo}
              alt="HTML logo"
            />
            {hoveredItem === 'html' ? <p className="font-bold">HTML</p> : ""}
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              onMouseOver={() => setHoveredItem('js')}
              onMouseOut={() => setHoveredItem(null)}
              className="w-20 mx-auto"
              src={JavaScriptLogo}
              alt="Js Logo"
            />
            {hoveredItem === 'js' ? <p className="font-bold">JavaScript</p> : ""}
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              onMouseOver={() => setHoveredItem('mongo')}
              onMouseOut={() => setHoveredItem(null)}
              className="w-20 mx-auto"
              src={MongoLogo}
              alt="Mongo Logo"
            />
            {hoveredItem === 'mongo' ? <p className="font-bold">Mongo DB</p> : ""}
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              onMouseOver={() => setHoveredItem('mysql')}
              onMouseOut={() => setHoveredItem(null)}
              className="w-20 mx-auto"
              src={MysqlLogo}
              alt="Mysql Logo"
            />
            {hoveredItem === 'mysql' ? <p className="font-bold">MySQL</p> : ""}
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              onMouseOver={() => setHoveredItem('node')}
              onMouseOut={() => setHoveredItem(null)}
              className="w-20 mx-auto"
              src={NodeLogo}
              alt="Node Logo"
            />
            {hoveredItem === 'node' ? <p className="font-bold">Node JS</p> : ""}
          </div>
        </div>
      </div>
    </div>
  );
};

代码优化方案

将技术卡片抽成独立组件,每个组件自行管理hover状态,大幅减少重复代码:

// 新建TechCard组件
const TechCard = ({ logo, alt, name }) => {
  const [isHovering, setIsHovering] = useState(false);

  return (
    <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
      <img
        onMouseOver={() => setIsHovering(true)}
        onMouseOut={() => setIsHovering(false)}
        className="w-20 mx-auto"
        src={logo}
        alt={alt}
      />
      {isHovering ? <p className="font-bold">{name}</p> : ""}
    </div>
  );
};

// 简化后的Experience组件
const Experience = () => {
  return (
    <div
      name="experience"
      className="w-full h-screen bg-[#0a192f] text-gray-300"
    >
      <div className="max-w-[1000px] mx-auto flex flex-col justify-center w-full h-full">
        <div>
          <p className="text-4xl font-bold inline border-b-4 border-purple-800">
            Experience
          </p>
          <p className="py-4">Technologies I have worked with</p>
        </div>
        <div className="w-full grid grid-cols-2 sm:grid-cols-4 gap-4 text-center py-8">
          <TechCard logo={CssLogo} alt="Css Logo" name="CSS" />
          <TechCard logo={HtmlLogo} alt="HTML logo" name="HTML" />
          <TechCard logo={JavaScriptLogo} alt="Js Logo" name="JavaScript" />
          <TechCard logo={MongoLogo} alt="Mongo Logo" name="Mongo DB" />
          <TechCard logo={MysqlLogo} alt="Mysql Logo" name="MySQL" />
          <TechCard logo={NodeLogo} alt="Node Logo" name="Node JS" />
        </div>
      </div>
    </div>
  );
};

内容的提问来源于stack exchange,提问作者ChrisWill303

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:50:22