Skip to content
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

Can't use non-three.js elements like <div> inside a <Canvas>? #47

Closed
AndrewRayCode opened this issue Mar 26, 2019 · 6 comments
Closed

Comments

@AndrewRayCode
Copy link

Again i'm a reconciler newcomer, but these lines look suspect in the createInstance method:

https://github.com/drcmda/react-three-fiber/blob/master/src/reconciler.js#L129-L130

    const target = catalogue[name] || THREE[name]
    instance = Array.isArray(args) ? new target(...args) : new target(args)

Two things seem to happen. First, the error itself seems to be getting eaten somewhere, but I'm not sure where. All that's logged is

The above error occurred in the <ul> component:
    in ul (created by SelectableMenu)

But the error itself seems to be logged after that statement:

Uncaught TypeError: target is not a constructor

This error itself isn't this most obvious to debug.

Why would I want to put a <div> inside a <Canvas> you ask? I'm using react-portal to make my 3d menu element also be able to render a DOM element, and have both the 3d element and GUI element use the same props. It's pretty convenient.

That doesn't seem compatible with this library. Do you have a suggestion for another approach?

@drcmda
Copy link
Member

drcmda commented Mar 26, 2019

See #34

A reconciler renders JSX into a target. react-dom renders into the dom, react-three-fiber renders into a threejs scene. You can't mount a div into a scene.

@drcmda drcmda closed this as completed Mar 26, 2019
@AndrewRayCode
Copy link
Author

Makes sense. I was able to do it with react-three-renderer but I don't think that uses a customer reconciler internally.

@giulioz
Copy link
Member

giulioz commented Apr 11, 2019

May it be possible to use useThree() hook outside of Canvas elements?
I need to have a ref to the camera for using with DOM components outside of canvas, and the only way I found to do so is using a component inside which passes the camera to parent with an event, but it's ugly.

A solution may be adding something like domChildren prop to , to have them excluded by the renderer but still be able to access useThree().

@drcmda
Copy link
Member

drcmda commented Apr 11, 2019

useThree is context based, it only works inside canvas. But it goes deeper, generally the real three canvas isn't created in line with the Canvas component. Just because Canvas has rendered and the parent gets its useEffect ping doesn't mean that the three js stuff is ready yet. React decides when it will render, and it seems to do it async by default. So the only safe way is to pass the camera up when it becomes available.

But you still have multiple options here.

  1. Canvas has a onCreated event that gives you the cam (+ state)
function Parent() {
  return <Child onCreated={({ camera }) => console.log(camera)} />
}

function Child(props) {
  return <Canvas {...props} />
}
  1. Canvas can render a function child that gives you the cam (+ state)
<Canvas>
  {({ camera }) => ... }
  1. Create and manage your own camera: https://github.com/drcmda/react-three-fiber#heads-up-display-rendering-multiple-scenes

@linonetwo
Copy link
Contributor

Can CSS2DRenderer in THREE fits in this situation?

@drcmda
Copy link
Member

drcmda commented Jun 21, 2019

gsimone pushed a commit that referenced this issue Sep 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants