组件渲染问题(长读)

Component Render Issues (Long Read)

我正在从我的数据库动态获取数据以显示在我的网站上,但我遇到了一个问题,不知道如何解决。

我有一个主主页,其中加载了一堆图块,您可以单击这些图块并将您带到我的 SPA 上的另一个页面。您可以单击的某些图块可以渲染文件中的 STL 对象,或者某些图块在单击时不会呈现。

我在渲染 STL 文件的组件中遇到问题。

有问题?

  1. 可点击组件是多重渲染我的模型组件(或类似的东西?)
  2. 我为每个页面视图卸载和重新装载 <Model/>
  3. 项目设置的一般问题?
  4. STL(模型)组件的问题可以在底部找到

已提供

  1. Home.js(主要成分)
  2. ClickableImage(组件 returns [])
  3. Layout.js(动态内容页面)
  4. Model.js(加载我的模型的组件)
  5. 可重现的代码当前问题CodeSandBox

更新

11:03pm Feb 23 : Added in CodeSandBox

codesandbox代码解释。 2 显示图像,单击第一张图像将带您进入未加载到 STL 文件中的布局。第二张图可以。那就是一切都崩溃的时候。

在Model.js下`/src/components/Layout/

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 && 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> 粘贴到我的主页组件中。

PreHome 粘贴

在主页组件中粘贴 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 最有可能引发我的错误,我不知道为什么。 (只知道这个是因为当我把它注释掉时错误就消失了)

如果需要更多信息,请联系。

问题是 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);
    // ...

See it live 在你的 Codesandbox 的分支上。

此外,如果您的实际资源 URL 并非 public(即需要某种身份验证),您可以遵循 this discussion。在这种情况下,您可以先将资源 .gtl 文件作为 arrayBuffer 获取,然后将其传递给加载程序。