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

如何在React.js中使用Hooks实现上述原生JS代码功能

在React中结合Hooks实现鼠标跟随卡片效果

原生JS代码的作用是监听父容器的鼠标移动事件,计算鼠标在每个卡片内的相对位置,通过CSS变量传递给卡片样式,实现跟随鼠标的视觉效果。下面是React Hooks的实现方案:

实现步骤

1. 组件结构与DOM引用

使用useRef获取卡片容器的DOM节点,替代原生的getElementById,符合React的DOM操作规范。

2. 事件处理函数

用useCallback包裹鼠标移动事件处理函数,保证函数引用稳定,避免useEffect重复执行。函数内部逻辑和原生代码一致:遍历所有卡片,计算鼠标相对位置并设置CSS变量。

3. 事件监听生命周期

通过useEffect在组件挂载时添加事件监听,卸载时移除,防止内存泄漏。

完整代码示例

import { useCallback, useEffect, useRef } from 'react';

function CardContainer() {
  // 获取卡片容器的DOM引用
  const cardsContainerRef = useRef(null);

  // 鼠标移动事件处理函数
  const handleMouseMove = useCallback((e) => {
    if (!cardsContainerRef.current) return;
    // 获取所有卡片元素
    const cards = cardsContainerRef.current.querySelectorAll('.card');
    cards.forEach(card => {
      const rect = card.getBoundingClientRect();
      // 计算鼠标在卡片内的相对坐标
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      // 设置CSS变量
      card.style.setProperty('--mouse-x', `${x}px`);
      card.style.setProperty('--mouse-y', `${y}px`);
    });
  }, []);

  // 管理事件监听的生命周期
  useEffect(() => {
    const container = cardsContainerRef.current;
    if (container) {
      container.addEventListener('mousemove', handleMouseMove);
      // 组件卸载时移除监听
      return () => container.removeEventListener('mousemove', handleMouseMove);
    }
  }, [handleMouseMove]);

  return (
    <div ref={cardsContainerRef} id="cards">
      {/* 这里可以放置动态生成的卡片,比如从props传入的列表 */}
      <div className="card">卡片内容1</div>
      <div className="card">卡片内容2</div>
      <div className="card">卡片内容3</div>
    </div>
  );
}

export default CardContainer;

配套CSS说明

需要保留原有的CSS变量使用逻辑,示例如下:

.card {
  position: relative;
  width: 300px;
  height: 200px;
  border-radius: 16px;
  background: #222;
  overflow: hidden;
}

.card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.1);
  border-radius: inherit;
  /* 使用CSS变量实现跟随效果 */
  transform: translate(calc(var(--mouse-x) * 0.05), calc(var(--mouse-y) * 0.05));
  transition: transform 0.2s ease;
}

注意事项

  • 如果卡片是动态生成的(比如通过map渲染props列表),无需额外处理,querySelectorAll会自动获取最新的卡片元素。
  • 若需要更精细的控制,也可以给每个卡片单独添加ref,但此场景下通过父容器批量获取元素的方式更简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:45:44