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
相关产品推荐
相关产品推荐

