threejs中group下绑定唯一key导致parten丢失的问题

发布时间:2024年01月02日

技术架构

  • 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 = [] } = props
  const [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.current
    if (!dragState) {
      return
    }
    const event: ThreeEvent<MouseEvent> = dragState.event as any
    console.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丢失了父子关系。

这是个有意思的问题,值得分享。

文章来源:https://blog.csdn.net/zoujiawei6/article/details/135336821
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。