useLoader 触发整个画布及其循环的重新渲染

问题描述 投票:0回答:1

我有 4 个文件,是使用文件输入选择的。它们被发送到specs组件,我使用react- Three-Fiber的textureLoader和useLoader钩子将组件渲染到场景。当我注释掉网格材质的贴图属性时,它将渲染 4 个平面,但是当我尝试添加纹理时,它将导致连续重新渲染。怎么解决。下面是代码。

import { useLoader } from "@react-three/fiber";
import React from "react";
import { DoubleSide, TextureLoader } from "three";

/**
 * specs value is in the order frame , stickL ,stickR
 * ,glass because it is being filtered in the handle input section
 *
 */
const specsValues = [
  { position: [0, -0.1, 0] },
  { position: [0.5, -0.1, -0.5], rotation: 0.5 * Math.PI },
  { position: [-0.5, -0.1, -0.5], rotation: -0.5 * Math.PI },
  { position: [0, -0.1, 0] },
];
//converst number into radian 
const Specs = ({ files }) => {
  console.log(files);
  function degToRad(x) {
    return x * (Math.PI / 180);
  }

  return (
    <mesh
      scale={[14, 6.75, 16.5]}
      position={[0, 22.5, 14]}
      rotation-x={degToRad(6)}
    >
      {files.map((e, index) => {
        return <Part image={e} key={index} index={index} />;
      })}
    </mesh>
  );
};

/**
 * specs value is in the order frame , stickL ,stickR
 * ,glass because it is being filtered in the handle input section
 *
 */

const Part = ({ image, index }) => {
  const imageUrl = React.useMemo(() => {
    if (typeof image === "string") {
      return image;
    } else {
      return URL.createObjectURL(image);
    }
  }, [image]);

  const texture = useLoader(TextureLoader, imageUrl); // Load texture only once

  // Clean up URL when component unmounts
  React.useEffect(() => {
    return () => {
      if (typeof image !== "string") {
        URL.revokeObjectURL(imageUrl);
      }
    };
  }, [image, imageUrl]);

  console.log(imageUrl);
  return (
    <mesh
      rotation-y={specsValues[index].rotation}
      position={specsValues[index].position}
    >
      <meshBasicMaterial
        color={"#fff"}
        side={DoubleSide}
        map={texture}
        // transparent={true}
        // map={useLoader(TextureLoader, imageUrl)}
      />
      <planeGeometry args={[1, 1]} />
    </mesh>
  );
};

export default Specs;

我尝试记住加载纹理功能并将图像文件作为依赖项传递,希望它不会重新渲染,但它不起作用。

该问题可能与每次创建的图像 url 不同有关。由于 useLoader 会在每次创建 url 时缓存 url,因此会将新的 url 传递给 useLoader,它将触发重新渲染。

reactjs three.js react-three-fiber
1个回答
0
投票

我通过在画布外执行 url 生成并将其作为 props 传递给画布来解决这个问题。但是如果有任何其他解决方案,请随时添加它们。

© www.soinside.com 2019 - 2024. All rights reserved.