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

如何在react-three-fiber中获取自定义3D对象id并绑定点击事件

问题解决说明

核心误区

document.getElementById 是浏览器用于查询DOM节点的专用API,你为Cell组件传入的id属性既不会挂载到DOM树上,也不会自动同步到Three.js的3D实例上,因此无法通过该方法获取3D对象。

推荐方案(直接绑定点击事件,无需主动查询对象)

React Three Fiber 内置了针对3D对象的指针事件系统,你可以直接在组件层级绑定点击事件,是最符合React开发习惯的实现方式:

  1. 改造Cell组件,接收点击事件回调并绑定到内部的3D对象上:
const Cell = ({ id, position, onClick }) => {
  return (
    // 将点击事件绑定到mesh上,触发时回传当前cell的id
    <mesh position={position} onClick={(e) => onClick?.(id, e)}>
      {/* 此处替换为你自己的几何体、材质代码 */}
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color="#fff" />
    </mesh>
  )
}
  1. 生成Cell时传入点击处理逻辑即可:
rowArr[col] = (
  <Cell
    key={`${props.side}-${row}-${col}`}
    id={`${props.side}-${row}-${col}`}
    position={position}
    onClick={(cellId, event) => {
      console.log('触发点击的cell id:', cellId)
      // 编写你自己的点击业务逻辑
    }}
  />
)

按需查询3D对象的方案

如果你确实需要根据id主动获取对应的3D实例,可以通过维护id与实例的映射表实现,比遍历场景查询效率更高:

  1. 父组件中定义映射表存储引用:
import { useRef } from 'react'

// 父组件内部
const cellInstanceMap = useRef({})
  1. 创建Cell时传入实例挂载回调:
rowArr[col] = (
  <Cell
    key={`${props.side}-${row}-${col}`}
    id={`${props.side}-${row}-${col}`}
    position={position}
    onMount={(instance, id) => {
      // 实例挂载后存入映射表
      cellInstanceMap.current[id] = instance
    }}
  />
)
  1. Cell组件中挂载完成后触发回调:
import { useRef, useEffect } from 'react'

const Cell = ({ id, position, onMount }) => {
  const meshRef = useRef(null)

  useEffect(() => {
    if (meshRef.current) {
      onMount?.(meshRef.current, id)
    }
  }, [id, onMount])

  return (
    <mesh ref={meshRef} position={position}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color="#fff" />
    </mesh>
  )
}

后续需要获取指定id的实例时,直接访问cellInstanceMap.current[目标id]即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:30:00