#javascript #reactjs #react-three-fiber #react-suspense
#javascript #reactjs #react-three-fiber #реакция-приостановка
Вопрос:
Я пытаюсь использовать текстуру для моего объекта ThreeJS. Я получаю сообщение об ошибке:
index.js:1 Error: Earth suspended while rendering, but no fallback UI was specified.
Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
in Earth
Earth.js:
export const Earth = () => {
const texture = useLoader(THREE.TextureLoader, earthImg)
return (
<Suspense fallback={<h1>Loading profile...</h1>}>
<mesh>
<sphereBufferGeometry attach="geometry" args={[5, 32, 32]} />
<meshStandardMaterial attach="material" roughness={1} fog={false} />
</mesh>
</Suspense>
)
}
index.js:
export default function App() {
return (
<Canvas
style={{height:'100vh',width:'100vw'}}
camera={{
position: [0, window.innerWidth / window.innerHeight, 5]
}}
>
<ambientLight intensity={0.5} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
<pointLight position={[-10, -10, -10]} />
<Earth position={[-1.2, 0, 0]} />
</Canvas>
)
}
Комментарии:
1.
useLoader()
должен вызываться из компонента, смонтированного внутри<Suspense>
виртуального DOM. Другими словами,<Suspense>
необходимо обернуть<Earth />
, а не возвращать из него.2. кроме того, fallback={<h1>Профиль загрузки …</h1> недопустим. h1 — это элемент dom. если вам нужны наложения dom в качестве запасного варианта, используйте библиотеку drei (в частности, Html-компонент) github.com/pmndrs/drei тогда вы можете сделать
fallback={<Html><h1>loading</h1></Html>}
>
Ответ №1:
Компонент, который useLoader()
вызывается из ( <Earth>
в данном случае), должен быть заключен в a <Suspense>
, резервный вариант ожидания не может быть указан внутри компонента.
Earth.js:
export const Earth = () => {
const texture = useLoader(THREE.TextureLoader, earthImg)
return (
<mesh>
<sphereBufferGeometry attach="geometry" args={[5, 32, 32]} />
<meshStandardMaterial attach="material" roughness={1} fog={false} />
</mesh>
)
}
index.js:
export default function App() {
return (
<Canvas
style={{height:'100vh',width:'100vw'}}
camera={{
position: [0, window.innerWidth / window.innerHeight, 5]
}}
>
<ambientLight intensity={0.5} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
<pointLight position={[-10, -10, -10]} />
<Suspense fallback={<h1>Loading profile...</h1>}>
<Earth position={[-1.2, 0, 0]} />
</Suspense>
</Canvas>
)
}