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

React按钮悬停切换图片报错:TypeError: btn.map is not a function

解决React组件悬停崩溃的问题:TypeError: btn.map is not a function

嘿,我一眼就找到了问题的根源!你遇到的崩溃是因为在鼠标移出事件里错误地把数组状态改成了单个对象,导致后续渲染时无法调用数组的map方法。

错误原因分析

你的初始状态btn是一个包含三个按钮对象的数组,但在mouseOutHandler函数里,你使用了btn.find()而不是btn.map():

  • find()方法只会返回匹配条件的第一个对象,而不是整个数组
  • 当你调用setBtn(btn.find(...))时,组件状态就从数组变成了单个对象
  • 下一次渲染时,你尝试对这个对象调用map()方法,自然会抛出TypeError: btn.map is not a function

另外,你的mouseOverHandler也有小问题:当遍历数组时,没有返回未匹配的元素,会导致数组里出现undefined,后续也可能引发渲染错误。

修正步骤

  1. 修正mouseOutHandler,用map()替代find(),确保始终返回完整的数组:
const mouseOutHandler = (id) => {
  setBtn(
    btn.map((item) => {
      if (item.id === id) {
        return { ...item, src: item.defaultSrc };
      }
      // 必须返回未修改的元素,保持数组结构完整
      return item;
    })
  );
};
  1. 完善mouseOverHandler,补上未匹配元素的返回语句:
const mouseOverHandler = (id) => {
  setBtn(
    btn.map((item) => {
      if (item.id === id) {
        return { ...item, src: item.hoverSrc };
      }
      // 返回原元素,避免数组出现undefined
      return item;
    })
  );
};

修正后的完整组件逻辑

这样修改后,你的状态始终保持数组结构,悬停和移出时只会更新对应按钮的src属性,不会破坏整个数组:

import { useState } from "react";

export default function App() {
  const [btn, setBtn] = useState([
    {
      id: 1,
      src: "https://via.placeholder.com/100?text=Default1",
      hoverSrc: "https://via.placeholder.com/100?text=Hover1",
      defaultSrc: "https://via.placeholder.com/100?text=Default1"
    },
    {
      id: 2,
      src: "https://via.placeholder.com/100?text=Default2",
      hoverSrc: "https://via.placeholder.com/100?text=Hover2",
      defaultSrc: "https://via.placeholder.com/100?text=Default2"
    },
    {
      id: 3,
      src: "https://via.placeholder.com/100?text=Default3",
      hoverSrc: "https://via.placeholder.com/100?text=Hover3",
      defaultSrc: "https://via.placeholder.com/100?text=Default3"
    }
  ]);

  const mouseOverHandler = (id) => {
    setBtn(
      btn.map((item) => {
        if (item.id === id) {
          return { ...item, src: item.hoverSrc };
        }
        return item;
      })
    );
  };

  const mouseOutHandler = (id) => {
    setBtn(
      btn.map((item) => {
        if (item.id === id) {
          return { ...item, src: item.defaultSrc };
        }
        return item;
      })
    );
  };

  return (
    <div className="App">
      {btn.map((item) => (
        <button
          key={item.id}
          onMouseOver={() => mouseOverHandler(item.id)}
          onMouseOut={() => mouseOutHandler(item.id)}
          style={{ border: "none", background: "transparent" }}
        >
          <img src={item.src} alt={`btn-${item.id}`} />
        </button>
      ))}
    </div>
  );
}

这样修改后,你的按钮悬停切换图片的功能就能正常工作,不会再崩溃啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:13:15