-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useLoader is throwing a Promise #3126
Comments
This is an implementation detail of Suspense. If you want to catch or detect errors, use an error boundary. |
Did you ever figure this out @alankent? Having a similar issue with useLoader + TextureLoader at the moment |
What is the issue exactly? Maybe see #3181 or #3181 (comment) specifically. |
It may be worth a separate issue/discussion but essentially I'm trying to fetch an external image and apply that image as a texture to a plane. After some finagling I managed to get the actual error that's happening from THREE:
There's basically no useful info online about this but after checking on the three.js discord and checking three.js source I figured out that it seems to be a UV issue, specifically that the texture channel is undefined for some reason. Manually setting it to 0 prevents the error from happening but the once the material is set it just disappears instead of applying the texture correctly. Abbreviated source: export default function Banner(props) {
useEffect(() => {
// Once the async fetching of data is done bannerData is set
if (bannerData) {
const tex = new THREE.TextureLoader().load(bannerData.image);
const material = new THREE.MeshBasicMaterial({ map: tex, transparent: true });
setMaterial(material);
}
}, [bannerData]);
const onClick = (event) => {
// onclick handler, not relevant
};
return (
<Suspense fallback={null}>
<Interactive onSelect={onClick}>
<mesh {...props} ref={mesh} scale={0.5} onClick={onClick} material={material}>
<planeGeometry
args={[formats[format].width * height, height]}
/>
{/* <meshBasicMaterial map={texture} transparent={true} /> */}
</mesh>
</Interactive>
</Suspense>
);
} |
I've found the root of my issue, after checking my example project lockfile I found it was relying on multiple different versions of three, so it was likely an API discrepancy. Deleting lockfiles and reinstalling so that only the latest three was depended on seems to have done the trick for me |
what version of three are you using across the board? It seems I get this issue as well, do i have to re-build one of my npm packages i'm using (realism-effects)? it only happens when i use ssgiEffects from this package |
In my case the version I settled on was r162, though I believe the API discrepancy was introduced in r151, so I believe as long as you're not depending on versions both before and after this you'd be okay. |
unfortunately i spoke too soon, i'm still getting an error. Really flustered. Here is my code: useFrame((state, delta) => { it states composerRef.current.render(delta); is giving me trouble. i'm using realism-effects and only happens when i do ssgiEffect. The HBAO, traa, and other effects have worked fine for me :( |
I am having this issue as well right now. I am using the useLoader hook with the STLLoader. "dependencies": {
"@react-three/drei": "^9.105.6",
"@react-three/fiber": "^8.16.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"three": "^0.164.1"
},
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@types/three": "^0.164.0",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.2.2",
"vite": "^5.2.0"
} I found a code sandbox: https://codesandbox.io/p/sandbox/gifted-varahamihira-rrppl0y8l4?file=%2Fsrc%2FApp.js and I just modified it to include the useLoader hook and it seems to work fine. The versions in that sandbox are:
I am going to try installing these exact versions locally and see if I have better luck. I feel like this is something worth digging into more since I just followed the getting started guide in the docs today and it is borked. |
So actually, I found the solution and didn't need to change any package versions. Turns out the problem was in the way my model component was setup. I was using state and useEffect to try loading the geometry from the url. For some reason that causes issues, my guess is with Suspense (I admittedly don't have a lot of experience with it). Going from this: function STLModel({ url }: STLModelProps) {
const [geometry, setGeometry] = useState<BufferGeometry | null>(null)
useEffect(() => {
if (!url) return
try {
const geometry = useLoader(STLLoader, url)
setGeometry(geometry)
} catch (error) {
if (error instanceof Error) {
console.error('Error loading STL model:', error.message)
} else if (error instanceof Promise) {
error.then((err: unknown) => {
console.error('Error loading STL model:', err)
})
} else {
console.error('Error loading STL model:', error)
}
}
}, [])
return geometry ? (
<mesh geometry={geometry}>
<meshStandardMaterial color="orange" />
</mesh>
) : null
} to this: function STLModel({ url }: STLModelProps) {
let geometry: BufferGeometry | null = null
geometry = useLoader(STLLoader, url)
return geometry ? (
<mesh geometry={geometry}>
<meshStandardMaterial color="orange" />
</mesh>
) : null
} Not only does this solve the problem, but also simplifies the code a lot! Maybe this will help someone else out. |
I have the following code in a largish application:
The 'e' variable is a promise.
So
useLoader
is throwing a promise, which .then() returns as undefined.Is
useLoader
meant to throw a promise as an exception, or is there something going wrong here?My overall app in this case is trying to load all the models to show on an animation timeline, including adding additional blend shapes to the models after loading. But I comment out all the other code, and I still get the above.
Thanks!
The text was updated successfully, but these errors were encountered: