No React, estou usando @react-three/fiber
para coisas 3D. Há muitos componentes que não suportam a maneira declarativa de fazer as coisas e exigem refs e código imperativo (por exemplo, CameraControls
de drei).
Estou tentando inicializar um CameraControls
na inicialização:
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} />
...
)
Claro que isso não funciona, pois na primeira e única vez useEffect
que é executado, o cameraRef.current
ainda é null
.
Quando tento usar o hack de timeout, o current ainda é nulo:
useEffect(() => {
setTimeout(resetCamera, 0)
}, [])
Quando aumento o tempo limite para algumas centenas de ms, ele começa a funcionar:
useEffect(() => {
setTimeout(resetCamera, 500)
}, [])
Essa abordagem com tempo limite é hackeada e ruim, buscando algo melhor.
Existe uma maneira de escrever um gancho personalizado que retorne refObject
e, mais tarde, quando o atual for preenchido pela primeira vez, execute a função fornecida?
Você pode armazenar a referência com
useState
, usando a função de estado definido como uma função de retorno de chamada ref , em vez de uma referência de objeto.Como o estado definido seria chamado quando a referência estivesse disponível, o estado mudaria e
useEffect
seria acionado:Se você usar a referência apenas
setLookAt
uma vez e não precisar armazená-la, basta chamarresetCamera
diretamente daref
propriedade deCameraControls
: