如何正确实现Next.js <Image />组件鼠标悬停切换src的功能
问题原因
第一版代码死循环原因
你直接在组件根渲染逻辑中调用setImgSrc,React组件每次渲染都会执行这段switch逻辑,每次执行就触发state更新,state更新又触发重渲染,形成无限循环触发渲染限制。
第二版代码hover无效原因
普通变量修改不会触发React组件重渲染,事件回调中修改imgSrc后组件不会重新渲染,<Image />的src属性不会得到更新,自然看不到效果。
额外注意:你的原有代码中把
default作为变量名是错误的,default是JS保留关键字,不能用作变量/常量名。
正确实现方案
你需要拆分逻辑:一是根据log.status设置基础图片源,二是在log.status为空时通过hover状态切换默认图的展示,具体实现如下:
import Image from 'next/image'; import { useState, useMemo } from 'react'; import A from "../../public/A.svg"; import B from "../../public/B.svg"; import C from "../../public/C.svg"; import defaultImg from "../../public/default.svg"; // 请补充导入你的悬停态默认图资源 import defaultHover from "../../public/defaultHover.svg"; function Status({ log }) { // 单独维护hover状态,仅在status为空时生效 const [isHover, setIsHover] = useState(false); // 用useMemo计算图片源,仅依赖项变化时才重新计算,避免无效重复执行 const imgSrc = useMemo(() => { switch (log?.status) { case "A": return A; case "B": return B; case "C": return C; case "": default: // status为空时根据hover状态返回对应资源 return isHover ? defaultHover : defaultImg; } }, [log?.status, isHover]); return ( <div onMouseOver={() => !log?.status && setIsHover(true)} onMouseOut={() => !log?.status && setIsHover(false)} > {/* Next.js Image组件必须填写alt、宽高属性,如使用fill模式请自行调整父容器定位属性 */} <Image src={imgSrc} alt="状态标识" width={24} height={24} /> </div> ); }
核心优化点
- 避免在组件根渲染逻辑中直接调用setState,从根源上解决无限重渲染问题
- 用state管理hover状态,修改state会触发组件重渲染,保证
<Image />的src属性同步更新 - 用useMemo缓存图片源计算结果,仅在依赖项变化时重新计算,减少不必要的性能消耗
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

