hmans / three-elements

Web Components-powered custom HTML elements for building Three.js-powered games and interactive experiences. 🎉
https://three-elements.hmans.co
MIT License
398 stars 14 forks source link

Figure out how to do better onupdate callbacks in React #6

Open hmans opened 3 years ago

hmans commented 3 years ago

three-elements works fine in React, with the single caveat that you need to work with React refs in order to register update callbacks. This isn't much of a problem, but ideally we'd want to be able to directly assign functions or references to functions to onupdate and friends from with JSX.

This currently isn't possible because React will swallow the entire attribute, which is discussed at length in this thread and this in the React repository.

Further reading:

hmans commented 3 years ago

Right now, a somewhat clunky but workable workaround is to just use refs:

const Thingy = ({ speed = 1 }) => {
  const rotate = (el) => (dt) =>
    (el.object.rotation.x = el.object.rotation.y += speed * dt)

  return (
    <three-mesh ref={(el) => (el.onupdate = rotate(el))}>
      <three-dodecahedron-buffer-geometry />
      <three-mesh-standard-material color="hotpink" />
    </three-mesh>
  )
}
hmans commented 3 years ago

This might also help: https://github.com/webcomponents/react-integration

justinfagnani commented 3 years ago

We have a new version of that concept we're working on for the next release of Lit: https://github.com/Polymer/lit-html/blob/lit-next/packages/labs/src/frameworks/react/create-component.ts

It's not Lit specific, so you could use it with your classes.

calebdwilliams commented 3 years ago

In the meantime you might consider something like JSX-native-events. I talk about that a bit in this article in CSS-Tricks.

hmans commented 3 years ago

I'll take a look, thanks!

hmans commented 3 years ago

We now have an experimental @three-elements/proxy package that can generate framework glue (here's a @three-elements/preact package that uses it for Preact.) I'm relatively sure that this will help us sort out the React issue too, by providing some glue that transparently creates React Components wrapping three-elements tags (yeah, it's wild.)