birkir / react-three-gui

GUI tools for react-three-fiber and react-spring
528 stars 29 forks source link

Suggestion: bring back the contextless API #25

Closed AndrewPrifer closed 3 years ago

AndrewPrifer commented 3 years ago

I remember one of the reasons react-three-gui was so perfect for react-three-fiber was that it didn't rely on context, which can't pass reconciler barriers. You could create control hooks anywhere down the component tree.

Right now this doesn't seem to be possible because the context has to be placed above Canvas in the component tree in order for the Controls component to work, so your hooks also have to be placed above the Canvas element, which makes colocating them with their respective components impossible.

If the reason for switching to context was to avoid having to implement global state and reactivity inside the module, I suggest using Zustand. Zustand also doesn't use context for its state store, so it solves the above problem, while at the same time taking the responsibility over from react-three-gui, the same way context does.

birkir commented 3 years ago

Reasoning for switching to Context:

  1. I used a simple EventEmitter that broke react hot reload (controls disappeared) which all was fixed with a hacky incremental counter to update the state. Very janky.
  2. Global things are not the best thing in the world. Previous implementation did not allow for two gui tools running on the same page.
  3. Standards, I mean a Provider and Consumer for something is pretty much the standard in these libs today.

But on the other hand, I don't truly understand the use-case you are going for, are you able to show me a small code-pen how things used to be able to work, and how it wont anymore? Hooks currently do not have to be placed above the canvas element, as per the codesandbox in readme. If it would, I would call that broken.

I will check out zustand, maybe that makes perfect sense.

AndrewPrifer commented 3 years ago

I'm staring at the example and I'm honestly not sure why it works. :D

My issue is essentially the same as #23, you can find more information about it here: https://github.com/pmndrs/react-three-fiber/issues/43

There's no big magic, I essentially want to put my useControl hooks in arbitrary nested components, like your example does.

Zustand which I mentioned, avoids context, just like redux is preparing to do so as well, exactly for this reason.

Edit: this issue actually seems to be an exact duplicate of #23 so I'm closing it. Interestingly, #23 also suggests the use of zustand. ;)

AndrewPrifer commented 3 years ago

I played around a bit more with your example, and it seems the only reason it works is because ControlsProvider and Canvas are in the same component. As soon as you nest the Canvas component one level deeper (codesandbox), it breaks the way I described.

AndrewPrifer commented 3 years ago

Closing as it is a duplicate of #23.