Проблемы с визуализацией компонентов (длительное чтение)

#reactjs #react-three-fiber

#reactjs #реакция-трехволоконная

Вопрос:

Я динамически получаю данные из своей базы данных для отображения на своем веб-сайте, но я столкнулся с проблемой и не знаю, как ее исправить.

У меня есть главная домашняя страница, которая загружается в виде набора плиток, по которым вы можете щелкнуть и перейти на другую страницу в моем SPA. Некоторые плитки, на которые вы можете щелкнуть, могут отображать объекты STL из файла, или некоторые плитки не будут отображаться при нажатии.

Я столкнулся с проблемой с моими компонентами, которые отображают файлы STL.

Проблемы?

  1. Интерактивный компонент — это множественный рендеринг моего компонента модели (или что-то в этом роде?)
  2. У меня есть размонтировать и перемонтировать <Model/> для каждого просмотра страницы?
  3. Общая проблема с настройкой проекта?
  4. Проблема с компонентом STL (Model) может быть найдена внизу

Предоставлено

  1. Home.js (основной компонент)
  2. Интерактивное изображение (компонент, который возвращает [])
  3. Layout.js (динамические страницы контента)
  4. Model.js (Компонент, который загружает мою модель)
  5. Воспроизводимый код Текущая проблема CodeSandbox

Обновления

11:03pm Feb 23 : Added in CodeSandBox

объяснение кода codesandbox. отображаются 2 изображения, нажатие на первое изображение приведет вас к макету, который не загружается в файл STL. Второе изображение делает. Вот когда все ломается.

В Model.js в разделе `/src/компоненты/ Макет/

Home.js

 class Home extends Component {
    render() {
        const {projects} = this.props;
        return (
            <section className="max-container">
                <div className="home-layout">
                    <div className="grid pl-4 pr-4">
                        <ClickableImage projects={projects}/>
                    </div>
                </div>
            </section>
        );
    }
}
 

Интерактивное изображение

 const ClickableImage = ({projects}) => {
    const mappedData = projects amp;amp; projects.map((project, index) => {
        return (
            <Link to={'/project3D/'   project.projectId} key={index}>
                <img
                    src={project.banner}
                    alt="img" className="clickImage"/>
            </Link>
        );
    })

    return (
        mappedData
    );
}

 

Layout.js (/project3D/)

 ...
<div className="content-div">
    <Canvas camera={{ position: [0, 10, 100] }}>
        <Suspense fallback={null}>
            <Model url={"./RaspberryPiCase.stl"} />
        </Suspense>
        <OrbitControls />
    </Canvas>
</div>
...
 

Итак, это мой общий макет всего на моей странице.

Главная страница -> Щелкните Изображение -> Страница макета.

Теперь это то, где все становится немного странным.

Canvas Часть на моей странице макета выдает мне эту ошибку при попытке ее загрузить.

 Uncaught invalid array length react-reconciler.development.js:7648
 
 The above error occurred in the <Model> component:

Model@http://localhost:3000/static/js/main.chunk.js:2430:15
Suspense
Canvas@http://localhost:3000/static/js/0.chunk.js:137042:66

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
 

Но когда я копирую раздел Canvas в свой Home Component , он без проблем отобразит мой STL-файл, а затем также загрузит мой STL-файл на мою другую страницу.

Вот изображения, чтобы показать вам проблему без вставки <Canvas> в мой домашний компонент.

Предварительная вставка

введите описание изображения здесь
введите описание изображения здесь
введите описание изображения здесь

После вставки Canvas в домашний компонент

введите описание изображения здесь
введите описание изображения здесь

Model.js

 import React, {useEffect, useRef} from "react";
import {STLLoader} from "three/examples/jsm/loaders/STLLoader";
import {useLoader, useThree} from "react-three-fiber";

export const Model = ({url}) => {
    const geom = useLoader(STLLoader, url);

    const ref = useRef();
    const {camera} = useThree();
    useEffect(() => {
        camera.lookAt(ref.current.position);
    }, [camera]);

    return (
        <>
            <mesh ref={ref}>
                <primitive object={geom} attach="geometry"/>
                <meshStandardMaterial color={"orange"}/>
            </mesh>
            <ambientLight/>
            <pointLight position={[10, 10, 10]}/>
        </>
    );
};

 

Я только что изучил это еще немного, но, по-видимому, useLoader — это то, что, скорее всего, выдает мою ошибку, и я не знаю почему. (Знайте это только потому, что, когда я комментирую это, ошибки исчезают)

lmk, если требуется дополнительная информация.

Комментарии:

1. откуда это useLoader берется? Также у вас нет никакой зависимости useEffect() , что означает, что он будет запускаться при каждом повторном рендеринге. Это нормально?

2. useLoader исходит из react-three-fiber того, что я добавил в инструкции import. Также обновлено useEffect с зависимостью от камеры. Все те же проблемы даже после этих изменений Error: invalid array length

3. не могли бы вы, пожалуйста, поделиться воспроизводимым примером, немного расширив тот CodeSandbox, которым вы поделились? Похоже, какая-то проблема связана с навигацией и рендерингом / удалением изображения. Поможет высококачественная демонстрация, которая воспроизводит ошибку.

4. разберусь с этим. Будет обновляться по завершении

5. @tmilar codesandbox.io/s/condescending-khorana-bnbf7

Ответ №1:

Проблема в том, что useLoader() возникают проблемы с извлечением файла, который вы предоставляете в url переменной.

В вашем примере значение, которое вы в конечном итоге предоставляете как «url», равно "./RaspberryPiCase.stl" .

Чтобы устранить вашу проблему, просто укажите полный абсолютный URL-адрес, с которого можно получить ваш STL-файл.

Основываясь на предоставленном вами Codesandbox, он находится в /public папке вашего проекта, поэтому простой способ исправить вашу проблему — выполнить:

 export const Model = ({url}) => {
    const fullUrl = `${window.href.origin}${url.replace(".", "")}`;
    const geom = useLoader(STLLoader, fullUrl);
    // ...
 

Посмотрите это вживую на развилке вашего Codesandbox.

Кроме того, вы можете следить за этим обсуждением, если ваш фактический URL-адрес ресурса на самом деле не был общедоступным (т. Е. требуется какая-то аутентификация). В этом сценарии вы можете .gtl сначала извлечь файл ресурсов в виде буфера массива, а затем передать его своему загрузчику.

Комментарии:

1. должно быть, я шучу, это было . . Большое вам спасибо.