bucklescript-tea icon indicating copy to clipboard operation
bucklescript-tea copied to clipboard

Question: TEA with React based virtual dom

Open tcoopman opened this issue 6 years ago • 19 comments

This is just a question. I was wondering if it would be possible (and be useful) to create tea with React as the view layer.

The reason why it could be useful for me is: some of the hooks that react has (for example componentDidMount) are useful when you integrate with existing js code. This is something I don't know how to do with the current vdom layer.

Other reasons why it can be useful:

  • Not having to create/maintain an own vdom layer
  • Huge React eco system that can be used
  • React also has React-Native, so this could be useful as well.

I haven't thought this through completely so there might be some obvious downsides or reasons why this isn't a good idea, so I'd love to get an opinion on this.

tcoopman avatar Jul 23 '17 06:07 tcoopman

JSX is possible I think. But reusing React's whole virtual DOM means a overhead to do conversion of the state back and forth like encoding and decoding JSON. It is actually more convenient if you wrap your React code in an external.

jackalcooper avatar Jul 24 '17 02:07 jackalcooper

This is just a question. I was wondering if it would be possible (and be useful) to create tea with React as the view layer.

Entirely possible and is on my todo list when bucklescript and reason settle down. :-)

The reason why it could be useful for me is: some of the hooks that react has (for example componentDidMount) are useful when you integrate with existing js code. This is something I don't know how to do with the current vdom layer.

Right now that is intended to be slated for the Custom type ( https://github.com/OvermindDL1/bucklescript-tea/blob/master/src/vdom.ml#L60 ) when I implement it. I've not committed any version of it yet as I keep coming up with different use-cases that it needs to support and I want to make sure I do it right. Basically a Custom node let's something basically hook into the vdom to handle all diffing itself. This will be great for doing things like hooking into react, embedding other tea components inside a tea component, etc...

I haven't thought this through completely so there might be some obvious downsides or reasons why this isn't a good idea, so I'd love to get an opinion on this.

The big obvious downside is that React's VDom has to assume mutable state, where mine does not (yay ocaml). That means that I make certain assumptions that would not hold in a mutable vdom world that react cannot do. I have a local benchmark where I test mine versus various other vdom's including React's, Matt's, Elm's, and AngularJS2, mine out-performs all of them in this test (chrome/firefox/edge) except Elm's where it is pretty on-par with it (and I can beat it in tests if I break the Elm api, which is also planned in an enhanced tea set of calls). It is not even well optimized just, just grabbed a few low-hanging fruits is all.

JSX is possible I think.

Indeed, ReasonML's JSX feature is just a PPX and could easily be used with TEA to generate TEA vdom (instead of react's). I need to get around to looking in to that sometime. :-)

It is actually more convenient if you wrap your React code in an external.

Which you could skip doing with my planned Custom vdom node. That will let you embed 'other' things, like React, in the vdom tree safely (unlike how Elm can break it pretty easily). You can already embed tea in React as it is, this will just let you continue the tree on without needing to use externals and so forth while keeping it all safe. :-)

OvermindDL1 avatar Jul 24 '17 16:07 OvermindDL1

There is https://github.com/gcanti/elm-ts which is TEA for TypeScript and it uses React as a view layer, but it is completely hide React, so you can not use lifecycle callbacks as far as I know.

Also using React as view layer will allow to do SSR. I mean you can compile your app to JS and run it in Node.js.

stereobooster avatar Feb 21 '18 22:02 stereobooster

but it is completely hide React, so you can not use lifecycle callbacks as far as I know.

Which is entirely doable yes, but the problem is that React is built with mutability in mind, so even if you are not mutating anything it is still performing a lot of work and checks that something like a purely immutable VDom does not need to do, hence why it is inherently slower.

Also using React as view layer will allow to do SSR. I mean you can compile your app to JS and run it in Node.js.

Oh good god that sounds horrible... Why would anyone want to run node.js on a server?! o.O

OvermindDL1 avatar Feb 21 '18 22:02 OvermindDL1

I agree with what you said.

Why would anyone want to run node.js on a server?! o.O

This is how you do SSR with React ¯\_(ツ)_/¯

stereobooster avatar Feb 21 '18 22:02 stereobooster

Lol, just another reason not to use React, good to know... ^.^;

To be honest, I'm actually leaning away from Bucklescript at this point, back to js_of_ocaml, because bucklescript keeps doing things that are not Ocaml'y and are breaking expectations of formats in it's API's and all (the more reasonml is changing the more I am really abhorring it's syntax...). Plus js_of_ocaml would allow for substantially easier ways to hook in PPX's. However a side effect is that js_of_ocaml outputs larger code compared to bucklescript (the main reason I started using bucklescript), which is why I've not switched to it at this time...

OvermindDL1 avatar Feb 21 '18 22:02 OvermindDL1

Plus hey, webassembly soon! Whooo! ^.^

OvermindDL1 avatar Feb 21 '18 22:02 OvermindDL1

They want to port Glimmer to WA (Glimmer is renderer for Ember.js). Also this one https://github.com/sebmarkbage/ocamlrun-wasm

WA is nice, but WebWorkers is much easier/approachable. Offload all work except DOM mutation and user interaction from main thread and this is all you need. See https://github.com/developit/stockroom

However a side effect is that js_of_ocaml outputs larger code compared to bucklescript

Google closure compiler in Advanced Mode? It's a pity there is no tool like https://github.com/angular/tsickle for js_of_ocaml/Reason.

stereobooster avatar Feb 21 '18 22:02 stereobooster

WA is nice, but WebWorkers is much easier/approachable.

Aren't those two entirely different things, like entirely different, in use-cases, what is done, etc... etc...? o.O?

Offload all work except DOM mutation and user interaction from main thread and this is all you need.

Which is what should be done in any case. I really like the fiber style of processing with distribution weighted against the render threads in native programs. I wish Javascript systems would catch up to these styles, instead they are still doing callback and promise hell (really, how backwards is that?!).

Google closure compiler in Advanced Mode?

Not tried it on it yet, was only performing cursory testing at the time. I should try that though and see how well it packs...

OvermindDL1 avatar Feb 21 '18 23:02 OvermindDL1

Aren't those two entirely different things

Yes sure. I mean you can use both to improve performance (in a different way).

stereobooster avatar Feb 21 '18 23:02 stereobooster

Yes sure. I mean you can use both to improve performance (in a different way).

Actually using Webassembly can cost you performance depending on what is done. The interface between webassembly and javascript is non-free, so if you cross that interface a lot then that can really cost you. As long as you 'batch' up commands/messages/whatever as much as possible then it's never really an issue, same when using webworkers actually. :-)

OvermindDL1 avatar Feb 21 '18 23:02 OvermindDL1

OOOO I'm not sure I understand this fully but if this means using react components in the bucklescript-tea I think this would be a KILLER FEATURE. This is something I noticed I wanted to do when experimenting Elm and the Elm Architecture. I've been playing with ReasonML in React Native and I wanted to also try adding Bucklescript-tea but not interacting with React was something that did not make it possible.

GTDev87 avatar Mar 14 '18 21:03 GTDev87

Yep, I designed it in mind so I'd be able to support the webcomponent style spec pretty easily (though first following the Elm as precisely as possible), that means that one could embed anything else 'into' this (and vice-versa if the parents are also built the same way).

OvermindDL1 avatar Mar 15 '18 20:03 OvermindDL1

Right now you can hack around it though (which you can't really do in elm). ^.^

OvermindDL1 avatar Mar 15 '18 20:03 OvermindDL1

Nice! Is there an example of bucklescript-tea using webcomponent or React hacked in?

GTDev87 avatar Mar 16 '18 02:03 GTDev87

I have been back away from web dev for months now but I hope this webcomponent/react-dom feature could see the light someday since it has been repeatedly brought up by various people. Maybe you can write a round map kind of thing on this so people have a clue where they should get started?

jackalcooper avatar Mar 16 '18 03:03 jackalcooper

Nice! Is there an example of bucklescript-tea using webcomponent or React hacked in?

Not as of yet for React as I don't use React, but I do have it embedded in a webcomponent ecosystem at work (polymer and vanillajs).

Maybe you can write a round map kind of thing on this so people have a clue where they should get started?

I definitely need to. Keep poking me and when I get time from work I definitely will! :-)

OvermindDL1 avatar Mar 19 '18 14:03 OvermindDL1

will be nice to see how we can use/experiment with web-components (even just gist).. For me is important to have working WC on project at the moment.

bultas avatar Dec 12 '18 12:12 bultas

For proper webcomponent handling I need to implement a layer to hook the custom elements lifecycle events to loading the application instead, and make a subscription for being able to 'listen' to DOM events, and lastly to make a command to 'send' DOM events. You can already listen by registering on the view currently though so the subscription is fluff, and you can send an event by making your own command, so the harder part is just the lifecycle events interaction, which is also something the user can create, but getting these all built it would be easier, however it is entirely possible for the user to do it all now as all needed extension points are exposed. I do need to get around to doing it sometime though I've not needed any project to do so as of yet, PR's are very welcome however! :-)

OvermindDL1 avatar Dec 12 '18 15:12 OvermindDL1