-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[v9] experiment: rework reconciler architecture, create objects on commit #2378
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 5b3a237:
|
118b33a
to
ae3c219
Compare
example/src/demos/Portals.tsx
Outdated
<Farm scale={10} rotation={[0, 0, 0]} position={[-1, -2, -10]} /> | ||
<Soda scale={5} position={[2, -2, -1.5]} /> | ||
<Suspense fallback={null}> | ||
<Farm scale={10} rotation={[0, 0, 0]} position={[-1, -2, -10]} /> | ||
<Soda scale={5} position={[2, -2, -1.5]} /> | ||
</Suspense> | ||
<Portal scale={[4, 5, 1]} position={[2, 0, -5]} rotation={[0, 0, 0]}> | ||
<Lights /> | ||
<Soda scale={8} position={[0, -2, -1.5]} /> | ||
<Environment preset="city" background="only" /> | ||
<Suspense fallback={null}> | ||
<Soda scale={8} position={[0, -2, -1.5]} /> | ||
<Environment preset="city" background="only" /> | ||
</Suspense> | ||
</Portal> | ||
</Portal> | ||
<Ramen scale={4} position={[-2, 0, 2]} /> | ||
<Soda scale={5} position={[1.5, 0, 3]} /> | ||
<Suspense fallback={null}> | ||
<Ramen scale={4} position={[-2, 0, 2]} /> | ||
<Soda scale={5} position={[1.5, 0, 3]} /> | ||
</Suspense> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR causes ULE in Portal
to fire without a ref attached outside of createPortal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like reconciler hook timings are really off for elements coming off of suspend as well.
import * as React from 'react'
import * as THREE from 'three'
import { suspend } from 'suspend-react'
import { createPortal, Canvas } from '@react-three/fiber'
function Test() {
suspend(async () => null, [])
const group = React.useRef<THREE.Group>(null!)
React.useEffect(() => console.log('Test useEffect', group.current?.uuid), [])
React.useLayoutEffect(() => console.log('Test useLayoutEffect', group.current?.uuid), [])
return <group name="Test" ref={group} />
}
function Portal({ children }: { children?: React.ReactNode }) {
const group = React.useRef<THREE.Group>(null!)
const [scene] = React.useState(() => new THREE.Scene())
React.useEffect(() => void console.log('Portal useEffect', group.current?.uuid), [])
React.useLayoutEffect(() => void console.log('Portal useLayoutEffect', group.current?.uuid), [])
return (
<group name="Portal" ref={group}>
{children && createPortal(children, scene)}
</group>
)
}
export default () => (
<Canvas>
<Portal>
<React.Suspense>
<Test />
</React.Suspense>
</Portal>
</Canvas>
)
Continued in #2465, dropping architecture changes. |
Fixes #2250 and a host of other issues when mutating a three.js object as an internal instance by separating the two and delegating three.js object creation until commit mount. This mitigates side-effects from creating objects and mutating them since the tree is now finalized and connected via instance descriptors.
An instance now looks like this, with
object
being the underlying three.js object andobject.__r3f
referring to its respectiveInstance
:Notably,
objects
was renamedchildren
and is used for all instances, regardless of the use ofattach
.memoizedProps
is nowprops
and indiscriminately contains elements' props.