I’m building a React application using Three.js and React Three Fiber. I’m trying to implement OrbitControls for my 3D scene, but I keep encountering the following error: “Cannot access ‘OrbitControls’ before initialization”. I’ve tried changing the way i import some modules, how i declare the canvas + contained elements and several solutions from online resources but nothing seems to work.
I’ve installed the three-stdlib package and imported the OrbitControls from it, and created a custom OrbitControls component using useThree and useEffect hooks to instantiate the OrbitControls class. However, when I try to render the OrbitControls component in the Canvas component, I get the following error: “target is not a constructor”.
Here’s my current code
import React, { useEffect, useRef, Suspense } from 'react';
import * as THREE from 'three';
import { OrbitControls as StdlibOrbitControls } from 'three-stdlib';
import { Canvas, useThree } from '@react-three/fiber';
import { Application } from '@splinetool/runtime';
import { ReactComponent as LogoC } from './images/logo-c.svg';
import { ReactComponent as MenuButton } from './images/menu-button.svg';
import { ReactComponent as RArrow } from './images/right-arrow-desktop.svg';
const SplineScene = () => {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
const app = new Application(canvas);
app.load('https://prod.spline.design/dulgIWpUS02bwIc2/scene.splinecode');
return () => {
app.destroy();
};
}, []);
return <canvas ref={canvasRef} />;
};
const Loading = () => {
return <div>Loading...</div>;
};
function OrbitControls() {
const { camera, gl } = useThree();
const controls = useRef();
useEffect(() => {
controls.current = new StdlibOrbitControls(camera, gl.domElement);
return () => controls.current.dispose();
}, [camera, gl.domElement]);
return null;
};
const Home = () => {
return (
<section className='fullPage'>
<nav className='navigation'>
<div className='logo'>
<LogoC />
</div>
<div className='menu-button'>
<MenuButton />
</div>
</nav>
<div className='home'>
<div className='heading-1'>
<span>Curious huh?</span>
<span>Us too.</span>
</div>
<div className='3d-image'>
<Canvas concurrent shadowMap>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Suspense fallback={<Loading />}>
<SplineScene />
</Suspense>
<OrbitControls />
</Canvas>
</div>
<div className='heading-2'>
<span>We're launching</span>
<div>
<span className='soon'>soon</span>
<div className='newsletter'>
<input className='newsletter-email-input' placeholder='your email goes here'></input>
<button className='newsletter-submit-button'>Let me know</button>
</div>
</div>
</div>
</div>
<footer className='contact'>
<div className='section-title'>
<span>Get in touch</span>
<span>
<RArrow />
</span>
</div>
<div className='social-links'>
<a href="https://www.twitter.com/xxxxxxx" target="_blank" rel="noopener noreferrer">Twitter</a>
<a href="https://www.instagram.com/xxxxxxx" target="_blank" rel="noopener noreferrer">Instagram</a>
<a href="https://www.linkedin.com/company/xxxxxxxxx" target="_blank" rel="noopener noreferrer">LinkedIn</a>
<a href="mailto:[email protected]" target="_blank" rel="noopener noreferrer">Email</a>
</div>
</footer>
</section>
);
};
export default Home;
–Errors–
target is not a constructor
TypeError: target is not a constructor
R3F: Canvas is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively