diff --git a/packages/fiber/src/core/reconciler.tsx b/packages/fiber/src/core/reconciler.tsx index fc3da40527..754034867a 100644 --- a/packages/fiber/src/core/reconciler.tsx +++ b/packages/fiber/src/core/reconciler.tsx @@ -159,7 +159,7 @@ function handleContainerEffects(parent: Instance, child: Instance, beforeChild?: // Bail if tree isn't mounted or parent is not a container. // This ensures that the tree is finalized and React won't discard results to Suspense const state = child.root.getState() - if (!parent.parent && parent.object !== state.scene) return + if (!parent.parent && parent.object !== state.internal.container) return // Create & link object on first run if (!child.object) { @@ -383,19 +383,19 @@ export const reconciler = Reconciler< appendInitialChild: appendChild, insertBefore, appendChildToContainer(container, child) { - const scene = (container.getState().scene as unknown as Instance['object']).__r3f + const scene = (container.getState().internal.container as unknown as Instance['object']).__r3f if (!child || !scene) return appendChild(scene, child) }, removeChildFromContainer(container, child) { - const scene = (container.getState().scene as unknown as Instance['object']).__r3f + const scene = (container.getState().internal.container as unknown as Instance['object']).__r3f if (!child || !scene) return removeChild(scene, child) }, insertInContainerBefore(container, child, beforeChild) { - const scene = (container.getState().scene as unknown as Instance['object']).__r3f + const scene = (container.getState().internal.container as unknown as Instance['object']).__r3f if (!child || !beforeChild || !scene) return insertBefore(scene, child, beforeChild) @@ -435,7 +435,7 @@ export const reconciler = Reconciler< commitMount() {}, getPublicInstance: (instance) => instance?.object!, prepareForCommit: () => null, - preparePortalMount: (container) => prepare(container.getState().scene, container, '', {}), + preparePortalMount: (container) => prepare(container.getState().internal.container, container, '', {}), resetAfterCommit: () => {}, shouldSetTextContent: () => false, clearContainer: () => false, diff --git a/packages/fiber/src/core/renderer.tsx b/packages/fiber/src/core/renderer.tsx index 3e10d72c06..4369e3e74c 100644 --- a/packages/fiber/src/core/renderer.tsx +++ b/packages/fiber/src/core/renderer.tsx @@ -315,7 +315,7 @@ export function createRoot( if (sceneOptions) applyProps(scene as any, sceneOptions as any) } - state.set({ scene }) + state.set((state) => ({ scene, internal: { ...state.internal, container: scene } })) } // Set up XR (one time only!) @@ -560,10 +560,13 @@ function Portal({ state = {}, children, container }: PortalProps): JSX.Element { return { // The intersect consists of the previous root state ...rootState, + ...injectState, get: injectState.get, set: injectState.set, - // Portals have their own scene, which forms the root, a raycaster and a pointer - scene: container as THREE.Scene, + internal: { + ...rootState.internal, + container, + }, raycaster, pointer, mouse: pointer, diff --git a/packages/fiber/src/core/store.ts b/packages/fiber/src/core/store.ts index 826d033199..3c6b093443 100644 --- a/packages/fiber/src/core/store.ts +++ b/packages/fiber/src/core/store.ts @@ -54,6 +54,7 @@ export const isRenderer = (def: any) => !!def?.render export type StageTypes = Stage | FixedStage export interface InternalState { + container: THREE.Object3D interaction: THREE.Object3D[] hovered: Map> subscribers: Subscription[] @@ -233,6 +234,8 @@ export const createStore = ( }, previousRoot: undefined, internal: { + container: null as unknown as THREE.Object3D, + // Events interaction: [], hovered: new Map>(),