three-elements icon indicating copy to clipboard operation
three-elements copied to clipboard

Figure out how to do better onupdate callbacks in React

Open hmans opened this issue 4 years ago • 6 comments

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 avatar Jan 08 '21 11:01 hmans

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 avatar Jan 08 '21 17:01 hmans

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

hmans avatar Jan 15 '21 17:01 hmans

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.

justinfagnani avatar Jan 15 '21 18:01 justinfagnani

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

calebdwilliams avatar Jan 27 '21 03:01 calebdwilliams

I'll take a look, thanks!

hmans avatar Jan 27 '21 09:01 hmans

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.)

hmans avatar Feb 04 '21 10:02 hmans