技术架构
- react
- threejs
- @react-three/drei
- @react-three/fiber
- @use-gesture/react
场景
一个分组下有一个Line,当使用gesture的useDrag触发事件以后:
import { Line } from '@react-three/drei'
import { ThreeEvent, useFrame } from '@react-three/fiber'
import { useDrag } from '@use-gesture/react'
import { useEffect, useState } from 'react'
import { DoubleSide, Vector3 } from 'three'const lineWidth = 4
const LinePropsData = {color: 0x3b61fa,lineWidth: lineWidth,dashSize: lineWidth,gapSize: lineWidth,side: DoubleSide,
}/*** 区域入参定义*/
export interface ExampleProps {positions?: Vector3[]
}const Example: React.FC<ExampleProps> = (props) => {const { positions = [] } = propsconst [linePositions, setLinePositions] = useState<Vector3[]>([...positions])useEffect(() => {if (!positions) {return}setLinePositions([...positions])}, [positions])const dragStateRef = useRef<GestureDragState>()const bind = useDrag((state) => {setDragState(state)})const bindObject = bind() as any// 每一帧更新 mesh 的位置useFrame(() => {const dragState = dragStateRef.currentif (!dragState) {return}const event: ThreeEvent<MouseEvent> = dragState.event as anyconsole.log('event.intersection.parent, event.intersections[0]?.object.parent)})return (<group {...bindObject}>{linePositions.length < 2 ? (// 两个以下的点构不成线<></>) : (<Line key={Math.random()} points={linePositions} {...LinePropsData} />)}</group>)
}export default Example
useFrame中获取相交对象的父级event.intersections[0]?.object.parent
,发现父级为null,而Line明明在group下,父级应该为group才对。一时间百思不得其解,重新写了个Line发现父级能找到group,对比之下,发现旧的写法里绑定了个key={Math.random()}
(暂时使用random代替源代码中的uuid生成),每次触发react重新渲染时都是渲染不同的元素,这导致了Line与group丢失了父子关系。
这是个有意思的问题,值得分享。