Hover效果在React里怎么实现才不卡顿?

司马雨诺 阅读 52

我最近在做一个卡片列表,想给每个卡片加个hover时显示操作按钮的效果,但用onMouseEnter/onMouseLeave写完后,鼠标快速移入移出时按钮会疯狂闪烁,感觉特别卡。是不是我的写法有问题?

我试过用CSS的:hover,但因为操作按钮是动态生成的,有些状态要从父组件传下来,所以还是得用JS控制。下面是我现在的代码:

const Card = ({ id }) => {
  const [isHovered, setIsHovered] = useState(false);
  
  return (
    <div
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
      style={{ padding: '16px', border: '1px solid #eee' }}
    >
      卡片 {id}
      {isHovered && <button>编辑</button>}
    </div>
  );
};
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
炳光
炳光 Lv1
你这个问题太典型了,每次鼠标进出都触发React重新渲染,快速操作时渲染跟不上就会卡要死。

最直接的解决办法:把显示隐藏交给CSS,JS只负责业务逻辑。

.card {
padding: 16px;
border: 1px solid #eee;
}

.card .action-btn {
display: none;
}

.card:hover .action-btn {
display: inline-block;
}


const Card = ({ id, actionButton }) => {
return (
<div className="card">
卡片 {id}
{actionButton}
</div>
);
};


这样hover完全靠CSS处理,一丁点JS渲染开销都没有。按钮内容通过props传入,父组件该传什么传什么,互不耽误。

如果你非要保留JS控制的状态(比如hover时还要做其他事情),可以换个思路,用CSS类名切显示状态,别用条件渲染:

const Card = ({ id }) => {
return (
<div
className="card"
onMouseEnter={(e) => e.currentTarget.classList.add('hovered')}
onMouseLeave={(e) => e.currentTarget.classList.remove('hovered')}
>
卡片 {id}
<button className="action-btn">编辑</button>
</div>
);
};


用DOM元素的classList直接改,不经过React状态,绕过重新渲染,直接起飞。

第一种方案最推荐,简单粗暴没毛病。
点赞
2026-03-13 14:02
司马含含
你这个问题大概率是因为按钮出现导致布局变化,鼠标滑到了空隙里触发了leave事件,所以疯狂闪烁。别用JS去控制DOM渲染了,直接把按钮渲染出来用CSS的opacity或者visibility控制显示隐藏,这样既没有布局抖动也不会触发React重渲染,性能最好。

const Card = ({ id, onEdit }) => {
return (
<div className="card-item">
卡片 {id}
<button onClick={onEdit} className="edit-btn">编辑</button>
</div>
);
};


配合这段CSS用:

.card-item .edit-btn {
opacity: 0;
visibility: hidden;
transition: opacity 0.2s;
}

.card-item:hover .edit-btn {
opacity: 1;
visibility: visible;
}
点赞 3
2026-03-03 22:25