This creates a new three-renderer and a new frameloop on every prop change, or when the component gets triggered, you’re pulling the rug. It makes little sense to use three in react like that because you’re mixing two conflicting worlds: oop and fp, loosing all interop. I would suggest you use react-three-fiber: Basic demo - CodeSandbox
And if we don’t want to use react-three-fiber, what would be the proposed solution? Also, I don’t think that’s correct since I put a console.log(‘useEffect’) in my useEffect() and it does not log. My stack trace looks a bit different.
in that case i wouldn’t use react. if you don’t want <div> but document.createElement(“div”) that’s vanilla js. ask yourself if not wanting react-dom in react makes any sense at all. the same exact thing applies to three. in the end mixing imperative and declarative is what’s causing the issues here, and always will, using react is the only sensible solution, it’s literally why it exists.
as for use effects, you can read about it here. the same applies to suspense or scheduling, react can unmount components at will, if your useEffect has side effects but no clean up phase you risk race conditions and double execution. as for logs, i’m not sure if that’s still true but react would hijack console.log, shutting it off so you didn’t see two logs but the effect ran twice anyway.
I was getting this error and my solution was to cancel the animation frame when my useEffect returns.
“RequestAnimationFrame returns a long integer value, the request id, that uniquely identifies the entry in the callback list. This is a non-zero value, but you may not make any other assumptions about its value. You can pass this value to window.cancelAnimationFrame() to cancel the refresh callback request.”
It’s ok for small projects but as you implement more features you will face more issues. I’m following your suggestion and am going to use react-three-fiber drcmda.
I stumbled upon this error whilst playing around with Three.js recently. My fix was to save an instance of WebGLRenderer in a useRef object so it is skipped across react’s lifecycle updates.
create a new reference directly to a DOM element react useRef
const rendererRef = useRef<WebGLRenderer>();
instantiate WebGLRenderer and update renderRef’s current value.