我在 React 中使用它@react-three/fiber
来实现 3D 内容。有很多组件不支持声明式操作方式,需要 refs 和命令式代码(例如CameraControls
drei)。
我正在尝试在CameraControls
启动时初始化:
const cameraRef = useRef<CameraControls>(null)
const resetCamera = () => {
if (cameraRef.current == null) return
cameraRef.current.setLookAt(
...cameraInitialPosition,
...cameraInitialTarget,
true
)
}
useEffect(resetCamera, [])
return (
<Canvas shadows>
<CameraControls ref={cameraRef} />
...
)
当然,这是行不通的,因为在第一次也是唯一一次useEffect
执行时,cameraRef.current
仍然是null
。
当我尝试使用超时破解时,当前仍然为空:
useEffect(() => {
setTimeout(resetCamera, 0)
}, [])
当我将超时时间增加到几百毫秒时,它开始工作:
useEffect(() => {
setTimeout(resetCamera, 500)
}, [])
这种带有超时的方法是糟糕的,需要寻找更好的方法。
有没有办法编写一些自定义钩子,让它返回refObject
,然后在当前第一次填充时执行提供的函数?
您可以使用 存储 ref
useState
,使用设置状态函数作为回调函数 ref,而不是对象 ref。由于当 ref 可用时会调用设置状态,因此状态将发生改变,并且
useEffect
会触发:如果你只使用 ref 调用
setLookAt
一次,并且不需要存储 ref,则resetCamera
直接从ref
的 prop调用CameraControls
: