如何在react-three-fiber中获取自定义3D对象id并绑定点击事件
问题解决说明
核心误区
document.getElementById 是浏览器用于查询DOM节点的专用API,你为Cell组件传入的id属性既不会挂载到DOM树上,也不会自动同步到Three.js的3D实例上,因此无法通过该方法获取3D对象。
推荐方案(直接绑定点击事件,无需主动查询对象)
React Three Fiber 内置了针对3D对象的指针事件系统,你可以直接在组件层级绑定点击事件,是最符合React开发习惯的实现方式:
- 改造
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> ) }
- 生成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与实例的映射表实现,比遍历场景查询效率更高:
- 父组件中定义映射表存储引用:
import { useRef } from 'react' // 父组件内部 const cellInstanceMap = useRef({})
- 创建Cell时传入实例挂载回调:
rowArr[col] = ( <Cell key={`${props.side}-${row}-${col}`} id={`${props.side}-${row}-${col}`} position={position} onMount={(instance, id) => { // 实例挂载后存入映射表 cellInstanceMap.current[id] = instance }} /> )
- 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
相关产品推荐
相关产品推荐

