useEffect 没有持续触发

useEffect is not firing consistently

该组件正在 3D 场景中创建一个 positionalAudio,并且可以使用 leva 调整音频对象。该对象正在按应有的方式创建,并且调整位置和旋转效果很好。无法正常工作的是改变音量。在 leva UI 中,我可以拖动音量的手柄进行更改,但没有发生任何效果(我假设这是因为 useEffect 在释放手柄之前触发并且实际上值没有变化尚未发生。在我释放句柄之前,至少会显示一个控制台日志)。当我将新值放入输入字段时,按回车键 useEffect 正在触发并且音量正在改变。不过只有这一次有效,以后就不行了。

import * as THREE from 'three'
import React, { Suspense, useRef, useEffect, useState } from 'react'
import { useThree, useLoader } from '@react-three/fiber'
import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js'
import { useControls } from 'leva'

function Sound({ url, volume }) {
    const sound = useRef()
    const { camera } = useThree()
    const [listener] = useState(() => new THREE.AudioListener())
    const buffer = useLoader(THREE.AudioLoader, url)
    useEffect(() => {
        sound.current.setBuffer(buffer)
        sound.current.setRefDistance(1)
        sound.current.setRolloffFactor(0)
        sound.current.setDirectionalCone(180, 230, 0.1)
        sound.current.setLoop(true)
        sound.current.play()
        const helper = new PositionalAudioHelper(sound.current)
        sound.current.add(helper)
        camera.add(listener)
        return () => camera.remove(listener)
    }, [])
    useEffect(() => {
      sound.current.setVolume(volume)
  }, [sound.current])
    return (
        <positionalAudio ref={sound} args={[listener]} />
    )
}

export default function App({ url, position}) {
    const { posXRight, posYRight, posZRight, rotationYRight, volumeRight } = useControls({
        posXRight: {
          value: position[0],
          min: -20,
          max: 20,
          step: 1
        },
        posYRight: {
            value: position[1],
            min: -20,
            max: 20,
            step: 1
          },
        posZRight: {
            value: position[2],
            min: -20,
            max: 20,
            step: 1
        },
        rotationYRight: {
            value: 0,
            min: 0,
            max: Math.PI * 2,
            step: Math.PI * 0.25
        },
        volumeRight: {
            value: 1,
            min: 0,
            max: 1,
            step: 0.05
        }
      })
  return (
      <Suspense fallback={null}>
        <mesh position={[posXRight, posYRight, posZRight]} rotation={[0, rotationYRight, 0]}>
          <sphereGeometry args={[0.1, 32, 32]} />
          <meshStandardMaterial color="white" />
          <Sound url={url} volume={volumeRight} />
        </mesh>
      </Suspense>
  )
}
useEffect(() => {
    sound.current.setVolume(volume)
}, [sound.current])

这个钩子在初始渲染和每次 sound.current 改变时触发(可能永远不会)。您应该将其更改为 [volume]