How to update geometry to be reused accross components

I am using react-three-fiber, and I have a geometry that changes asynchronously according to some variables in a useEffect. I am keeping this geometry isolated because I want to reuse it later accross different components. Like this:

const Geom = (props) => {
    const [isCube, setIsCube] = useState(false)

    useEffect(() => {
          // do something that changes geometry asynchronously 
          setIsCube(props.thing)
    }, [props])

    return (
    <>
    {isCube ? <boxGeometry/> : <sphereGeometry/>}
    </>
     )
}

And I use it in many places:

const firstMesh = (props) => {
      return (
      <mesh><Geom/><material/></mesh>
       )
}
const secondMesh = (props) => {
      return (
      <mesh><Geom/><differentMaterial/></mesh>
       )
}

My issue is that whenever the variables change and the useEffect gets fired (I know its being fired because breakpoints there activate) the other meshes dont “notice” this change and remain the same, until I change another one of their properties, which prompts a rerendering with the appropriate geometry. What am I doing wrong? I feel like this is a simple thing.

It is a simple thing in a non react context. Modify the geometry vertices… set the .needsUpdate flags on the attribute you modified, and any meshes sharing the geometry will update.

Maybe this is related to .needsUpdate?

You might want to try asking in the r3f discord channel?

Edit: I see you are swapping the geometry itself, not modifying it… so…

In vanilla you would have to manually replace the geoms on the meshes you want to change.

Perhaps instead of creating a new geometry, you could assign/copy the new attributes to the existing geometry?

1 Like

Thanks for the response! Not I sure I get what you mean. Are you saying I should use BufferGeometry and defines edges and such, instead of using sphere and box components?

A geometry has “attributes”, position, normal, and uv… you can copy the attributes from the new geometry to the old one… then any meshes using the old geometry will be updated.

If you are creating a new geometry, then you would have to regenerate all the meshes that are using the geometry… or keep track of those meshes and manually replace their .geometry with your new geometry.

Here is an R3F example of a shared geometry and you can modify one of the attribuites using the GUI

1 Like