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

如何正确实现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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:27:03