diff --git a/packages/r3f/src/extension/components/ProxyManager.tsx b/packages/r3f/src/extension/components/ProxyManager.tsx index 5bed892..863624a 100644 --- a/packages/r3f/src/extension/components/ProxyManager.tsx +++ b/packages/r3f/src/extension/components/ProxyManager.tsx @@ -1,4 +1,4 @@ -import type {VFC} from 'react' +import type {FC} from 'react' import React, {useLayoutEffect, useMemo, useRef, useState} from 'react' import type {Editable} from '../../main/store' import {createPortal} from '@react-three/fiber' @@ -25,7 +25,7 @@ type IEditableProxy = { editable: Editable } -const ProxyManager: VFC = ({orbitControlsRef}) => { +const ProxyManager: FC = ({orbitControlsRef}) => { const isBeingEdited = useRef(false) const editorObject = getEditorSheetObject() const [sceneSnapshot, editables] = useExtensionStore( @@ -69,9 +69,18 @@ const ProxyManager: VFC = ({orbitControlsRef}) => { object.parent!.remove(object) } else { editableProxies[theatreKey] = { - portal: createPortal( - , - object.parent!, + portal: ( + // we gotta wrap the portal because as of [this commit](https://github.com/pmndrs/react-three-fiber/commit/5d1652ce5b63397ad79c39d3dd100b26a465c41f) + // in react-three-fiber, portals use the uuid of their parent object as their own key. Since many of these objects are nested + // inside the same parent, they end up having the same react key. We avoid this issue by wrapping the portal in a component + // so that its react key is unique within its parent component. + , + object.parent!, + )} + key={`portal-wrapper-${theatreKey}`} + /> ), object: object, editable: editables[theatreKey]!, @@ -246,4 +255,8 @@ const ProxyManager: VFC = ({orbitControlsRef}) => { ) } +const PortalWrapper: React.FC<{portal: React.ReactNode}> = ({portal}) => { + return <>{portal} +} + export default ProxyManager