我有 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,它将触发重新渲染。
我通过在画布外执行 url 生成并将其作为 props 传递给画布来解决这个问题。但是如果有任何其他解决方案,请随时添加它们。