Cloning a group in R3F

Hi there,

i am building a configurator with r3f and zustand for the state management. I want to add a functionality to compare configurations. My idea is to clone the current configurations group at some point and offset it in its position to compare it. If i would just duplicate the Component all zustand values would also change the duplicate. So my idea was to clone the parent group and offset it as i did in this codesandbox:

https://codesandbox.io/p/devbox/cqqx7s

But this solution does not seem right at all. I could not get the <Clone /> Component from drei to work… maybe that would be a better solution? Or using a <primitive />. The problem i encountered when trying was that my refs to the group where undefined at first so i always got errors. I tried to fix it with useEffect and useMemo but could not make it work…
Has anybody a solution or an advice on how i could do this?

Think of a component as the deterministic outcome of a bunch of input values. Same values same outcome. Different values different outcome. If whatever it is that you want to configure in a certain way is abstracted correctly this wouldn’t even be a challenge, just mount two components with their respective configs.

Never clone indiscriminately, never call scene.add/remove, this is all dirty.

if you keep state at the parental level and make components configurabe to props, you gain a lot of flexibility and the code will be a lot cleaner and less wired.

const config1 = useStore(...)
const config2 = useStore(...)
return (
  <group>
    <Thing {...config1} />
    <Thing {...config2} positition-y={-1} />

function Thing({ color, hat, ...props }) {
  ...
1 Like

you can also keep the previous configs around

const config = useStore(...)
const prevconfig = useRef(config)
useEffect(() => prevconfig.current = config, [config])
return (
  <group>
    <Thing {...config} />
    <Thing {...prevconfig.current} positition-y={-1} />
2 Likes

Alright thanks for the informative answer. But the problem in my actual case is that the app is deeply nested so i used the useStore hooks to only rerender some part of the tree and not the entire group. As an example:

  • door element
    • door
      • door model
        • hinges
          • hinge models
            • hinge 1

If i change states at the top level and send them down all the small changes like hinge material would cause the whole tree to rerender right? I was trying to keep the unnecessary rerenders as little as possible. Is there another way than sending the configuration down the tree? Or should i just use the store the way you mentioned to have 2 independent configurations?