Jakub Pabis
Jakub Pabis

Reputation: 21

React Three Fiber, Three.js and Drei: lazy import models using components gets re-rendered to infinity

I'm trying to lazy import JSX models in React Three Fiber. I have a couple of JSX models which incorporate useGLTF() from drei, to load the actual .gltf/.glb model, as nodes and materials, like in the R3F tutorial.

What I'm trying to do now, is to lazy import those JSX model components on demand, through my ModelsLoader component.

The problem is that even when I use memo() or useMemo() from React, the component gets re-rendered constantly...

I don't know what I'm doing wrong, or even if what I'm trying to do is even possible, but hey, there are a lot of smart people here, some maybe you'll be able to help me ;)

example of my JSX model component, which I'm trying to lazy import in ModelsLoader component:

import React, { useRef } from 'react';
import { useGLTF } from '@react-three/drei';

export default function OCF155(props) {
  const { nodes } = useGLTF('models/EXAMPLE_MODEL.glb');
  const ref = useRef();
  return (
    <group {...props} ref={ref} dispose={null} type='TopParent'>
      <mesh
        name='EXAMPLE_MODEL'
        castShadow
        receiveShadow
        geometry={nodes.EXAMPLE_MODEL.geometry}
        material={nodes.EXAMPLE_MODEL.material}
        rotation={[Math.PI / 2, 0, 0]}
        scale={1}
      />
    </group>
  );
}

And here is my ModelsLoader component as it's stands for now, using .memo():

import React, { memo, lazy } from 'react';
import Selection from './helpers/Selection';

const ModelsLoader = memo(function ModelsLoader({ models }) {
  return (
    <>
      {models &&
        models.length > 0 &&
        models.map((model, index) => {
          const ModelComponent = lazy(() => import(`./models/${model.name}`));
          return (
            <Selection key={index}>
              <ModelComponent
                position={model.position}
                rotation={model.rotation}
              />
            </Selection>
          );
        })}
    </>
  );
});

export default ModelsLoader;

I was trying to do it without .memo(), but the result was the same. I was thinking, that if I use .memo(), hence the models list is not changing throughout the render of the page, it will get rendered once and then passed on...

Upvotes: 2

Views: 910

Answers (0)

Related Questions