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

JSX #179

Closed
iamjohnlong opened this issue Sep 29, 2017 · 23 comments
Closed

JSX #179

iamjohnlong opened this issue Sep 29, 2017 · 23 comments

Comments

@iamjohnlong
Copy link

I created an example of how to wire in JSX here https://jsfiddle.net/kqurpfqk/

Just an experiment, but I wanted to share. I'm curious of the perf impact which I will be testing soon.

@leeoniya
Copy link
Member

leeoniya commented Sep 29, 2017

neat.

i feel like additional pre-processing work would be required to translate 100% - if it's even possible. especially vnode's special _-prefixed attrs view's options. some of the data would need to be pre-processed to translate key -> _key for vnodes, and so on...

additionally, domvm's injectView becomes impossible, as well as injectElement. i think you'd lose a ton of features to boil down to the lowest common denominator. that's the main reason why i've been hesitant to provide a JSX layer.

@leeoniya
Copy link
Member

a TypeScript declaration file would be much more useful, IMO, as it would provide API discoverability and autocomplete for anyone using this lib with VSCode.

i have one started but it's far from finished as i'm not very well versed in finer details of the format.

@iamjohnlong
Copy link
Author

You could alway explicitly call domvm in the views. https://jsfiddle.net/wubt3xzr/1/

I'm not a fan of JSX, but it's easier to convince others to move away from React with JSX support.

@leeoniya
Copy link
Member

beautiful!...NOT 😜

if that's all the code that's required, then the perf overhead for that wrapper should be pretty negligible over defineElementSpread.

@leeoniya
Copy link
Member

btw, once enough JSX enthusiasts have sufficiently dogfooded your JSX pragma, we can add it to the docs inline.

@foxdonut
Copy link

Using babel-plugin-transform-react-jsx with pragma = domvm.defineElementSpread seems to work fine. Am I missing something?

Thanks.

@leeoniya
Copy link
Member

leeoniya commented Nov 25, 2017

i don't use React or JSX, so it's hard for me to tell from JSX examples where JSXisms end and Reactisms begin. how does it handle domvm's .-prefixed stringy props vs attrs? how does the babel pragma handle domvm's defineView components?

<MyButton color="blue" shadowSize={2}>...

someone would need to go through https://github.com/leeoniya/domvm#templates and document what can and cannot be supported by JSX.

@foxdonut
Copy link

Thank you @leeoniya for the quick response. I will have a closer look at the issues that you have raised and try to come up with some examples.

In the meantime, I'll say that simple/plain JSX seems to work well with what I stated above, so that's a good start.

@iamjohnlong
Copy link
Author

@foxdonut I don't think this will work with components. Have you written a component that works with this?

@foxdonut
Copy link

foxdonut commented Nov 26, 2017

@iamjohnlong since I am new to domvm, would you mind showing exactly what you mean by "component"? Could you show an example of what it does that cannot be accomplished with plain functions and using defineElement? Many thanks!

@iamjohnlong
Copy link
Author

there are a few examples in the demo's, http://leeoniya.github.io/domvm/demos/playground/#table-filter

docs are here https://github.com/leeoniya/domvm#sub-views-vs-sub-templates

"Sub views" being a component. This fiddle shows the use of a component https://jsfiddle.net/kqurpfqk/ and why the wrapper pragma is needed.

@foxdonut
Copy link

@iamjohnlong thanks, that is very helpful. I understand components and sub-views better now.

My personal preference would be to use sub-templates instead of sub-views, and plain functions instead of JSX components. For example, I would change Component in your fiddle example to this:

https://jsfiddle.net/foxdonut/01afeq9h/

It's not as "JSX-y", but like I said, I favour plain function calls. Then jsx can simply be defineElementSpread as you can see in the fiddle.

The table-filter example is very interesting and greatly helped me understand components and views in domvm. Again, while I'm not knocking this approach, I still favour plain functions. This would be my take on it:

https://codepen.io/foxdonut/pen/XzBVmN?editors=0010

Some advantages include:

  • plain functions and looser coupling
  • top-level model/single source of truth
  • no need for refs
  • no need to emit and listen to events
  • less framework/library-specific code.

It's trivial to use JSX:

https://codepen.io/foxdonut/pen/WXKMwR?editors=0010

Finally, because the view is a function of the model, you can have a dev tool that can record and tracer back through model snapshots, and also allow you to type in a model directly and see the resulting view:

https://codepen.io/foxdonut/pen/vWadgB?editors=0010
https://codepen.io/foxdonut/pen/VrBQpo?editors=0010

@leeoniya Please know that I understand that you don't like JSX, but I was hoping to figure out if this simple approach would make JSX easy to use for those who want to. I've been exploring many virtual-DOM libraries and domvm is currently my favourite.

@iamjohnlong
Copy link
Author

@foxdonut whatever floats your boat man. that's one of the great things about domvm, is that it's flexible and doesn't force you into one pattern.

@foxdonut
Copy link

@iamjohnlong agreed! really liking domvm.

My original concern was simply whether using JSX in this simple manner with domvm had any obvious/glaring disadvantages.

@tropperstyle
Copy link

One thing I notice is that the inner functions like onSearchChange would be recreated each render. Not sure if that would have any real world perf implications, or how that compares to the overhead of a sub-view though.

@foxdonut
Copy link

@tropperstyle that's a good point. Normally, I would organize the code slightly differently such that onSearchChange would only be created once.

That being said, I'm not certain about parameterized handlers, i.e. a function that takes a parameter and returns a handler function. Would those be recreated on each render, and how much impact would that have on performance or memory consumption? How does using domvm's parameterized handlers, onclick: [myFn, arg1, arg2], compare? Same question for delegated handlers.

I'd be interested in the differences there and their consequences.

@leeoniya
Copy link
Member

thanks for the praise 😊

My original concern was simply whether using JSX in this simple manner with domvm had any obvious/glaring disadvantages.

if you're just using JSX as a way to avoid el() calls, i don't really see any major issues. JSX offers the lowest common denominator, but there are numerous other factories in domvm that provide many things JSX cannot do. another issue is that svg has its own factory in domvm, whereas JSX does not and would need help to disambiguate that during transpilation. it would be rather awkward to use JSX in its most basic form and have to resort to domvm's factories for everything else. it's not because i dislike JSX, i just feel that the value you get from it and the cost of making the tooling "kinda work" is very not worth it. i would rather have uniform syntax throughout my view layer, and you cannot get this in domvm w/JSX without giving up a bunch of features. if you enjoy an IDE's JSX hinting/autocompletion, i would rather focus more effort on getting good TypeScript declarations to get the same from domvm's factories in VSCode (see #186)

One thing I notice is that the inner functions like onSearchChange would be recreated each render. Not sure if that would have any real world perf implications, or how that compares to the overhead of a sub-view though.

function recreation and re-binding is really cheap. i wouldn't worry about it until you have hundreds of handlers or extremely numerous/rapid redraw() calls.

That being said, I'm not certain about parameterized handlers, i.e. a function that takes a parameter and returns a handler function. Would those be recreated on each render, and how much impact would that have on performance or memory consumption? How does using domvm's parameterized handlers, onclick: [myFn, arg1, arg2], compare? Same question for delegated handlers.

all parameterized handlers bind the same proxy handler, so they will not get recreated or rebound. the parameterized array you provide just sits on the linked vnode and the proxy handler executes it at runtime when an event fires.

@foxdonut
Copy link

@leeoniya everything you said makes a lot of sense. thank you for the explanations.

I agree with you, using domvm's functions definitely results in more powerful and uniform code.

Still, it's nice to know that you can get a great deal of domvm's features with JSX and can work nicely say in an application where you don't need svg.

To answer your original question, here are the JSX equivalents of https://github.com/leeoniya/domvm#templates : https://codepen.io/foxdonut/pen/KyBzmy?editors=0010

Finally just to clear up the "Reactism vs JSXism" question, there really is no React involved here at all. JSX simply gets translated to defineElementSpread calls and that's it.

Cheers and thanks again for domvm, really awesome library.

@leeoniya
Copy link
Member

leeoniya commented Nov 27, 2017

To answer your original question, here are the JSX equivalents of https://github.com/leeoniya/domvm#templates : https://codepen.io/foxdonut/pen/KyBzmy?editors=0010

that's pretty cool :)

i don't foresee adding explicit support for JSX in domvm. but rather than keeping these brain-dumps/experiments in a permanently open issue, would you guys want to put this into a JSX wiki section here and i'll link to it from the main readme? afterwards we can close this out and anyone can add more to the wiki as they see fit.

@foxdonut
Copy link

@leeoniya great idea. I added a Wiki page: https://github.com/leeoniya/domvm/wiki/JSX

@leeoniya
Copy link
Member

leeoniya commented Nov 28, 2017

would you mind adding the contents of the codepen and jsfiddle directly to the wiki? i'd prefer not to rely on external services to host code samples (if you couldn't tell from my from-scratch demo playground impl ;). you can still leave the links, though.

@foxdonut
Copy link

Done!

@leeoniya
Copy link
Member

thanks! i've added it to the readme: https://github.com/leeoniya/domvm#jsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants