by novocantico on 8/16/24, 7:01 PM with 225 comments
by spankalee on 8/16/24, 10:59 PM
You want to return a description of the DOM, rather than the real DOM, because you want to be able to reevaluate your templates repeatedly with new state, and efficiently update the DOM where that template is rendered to.
All the examples here use imperative DOM APIs to do updates, like with this:
function TodoInput(attrs: { add: (v: string) => void }) {
const input = <input /> as HTMLInputElement;
input.placeholder = 'Add todo item...';
input.onkeydown = (e) => {
if (e.key === 'Enter') {
attrs.add(input.value);
input.value = '';
}
};
return input;
}
class TodoList {
ul = <ul class='todolist' /> as HTMLUListElement;
add(v: string) {
const item = <li>{v}</li> as HTMLLIElement;
item.onclick = () => item.remove();
this.ul.append(item);
}
}
Avoiding those `input.onkeydown = ...` and `this.ul.append(item)` cases, and instead just iterating over items in your template, is probably the main benefit of a VDOM.(The problem with VDOMs is that diffing is slow, a problem solved by using templates that separate static from dynamic parts, like Lit - a library I work on).
by novocantico on 8/16/24, 10:54 PM
[edit] Oh also, this solution works really well for SEO. That's another problem I didn't find solved well in other JSX frameworks.
by cribbles on 8/16/24, 10:37 PM
[1] https://engineering.fb.com/2010/02/09/developer-tools/xhp-a-...
by recursive on 8/16/24, 11:08 PM
https://github.com/tomtheisen/mutraction
It lets you do stuff like this.
const model = track({ clicks: 0});
const app = (
<button onclick={() => ++model.clicks }>
{ model.clicks } clicks
</button>
);
document.body.append(app);
by merlindru on 8/17/24, 7:30 AM
Another interesting thing is that other JSX libraries like Solid.JS also return DOM nodes, and I love that this idea is gaining traction
The closer we get to the platform we're using, the better. Being removed by layers of abstractions CAN be useful, but in practice, I haven't found a use for abstracting away the platform. (yet.)
Maybe huge projects like Facebook benefit from this tho (which I haven't worked on)
by sophiebits on 8/16/24, 10:34 PM
by flowerlad on 8/17/24, 12:17 AM
Here’s an app written using Vanilla TSX: https://github.com/wisercoder/eureka/tree/master/webapp/Clie...
by config_yml on 8/16/24, 10:10 PM
by girvo on 8/17/24, 2:30 AM
Uncaught (in promise) TypeError: Map.groupBy(...).entries().map is not a function
by slmjkdbtl on 8/17/24, 12:47 AM
h("div", {}, [
h("p", {}, "this is easy"),
...list.map((l) => h("li", {}, l),
])
With this you automatically get loops, variable interpolation etc without having to invent a compiler and new syntax. Can someone help me understand?by ibash on 8/16/24, 10:34 PM
No better article than this: https://blog.vjeux.com/2013/javascript/react-performance.htm...
by hizanberg on 8/17/24, 5:41 AM
Was super productive and easy to create a Cloudflare Worker Web App that’s free to host thanks to Cloudflare’s generous 100k daily worker request limit.
Generally don’t believe in serverless for larger Apps, but for small websites that you just want to create, deploy and ignore - it’s great!
by mg on 8/17/24, 6:52 AM
el = <button>Click me</button> as HTMLButtonElement;
What would be the downside of el = html.button('<button>Click me</button>');
?That way no compilation step would be needed and debugging would be easier as the code executed in the browser is the same code the developer writes.
by EugeneOZ on 8/17/24, 4:36 AM
After “How would they handle large data?” it turns into an unreadable mess.
Communication between elements is not covered, global deps, DOM updates scheduling, content projection, and so on - you “just don't need it” in small demo examples, but you do need it in the real apps.
by drikerf on 8/17/24, 6:29 AM
Clojure datastructures makes this so much more enjoyable. Everything is just basic lists and maps which makes it very flexible and powerful.
[:ul [:li "task 1"] [:li "task 2"]]
It's weird that it's not more common for making web apps.
by whazor on 8/17/24, 6:54 AM
by ilrwbwrkhv on 8/17/24, 3:16 AM
by andruc on 8/17/24, 1:36 PM
Not what you'd expect to see.
by talkingtab on 8/17/24, 12:33 PM
So I would like to explore the ability to use JSX in non-DOM environments. react-three-fiber does this with Threejs, but then it is still React oriented. I found this article about parsing JSX https://blog.bitsrc.io/demystifying-jsx-building-your-own-js.... And I know babel has something that parses JSX.
Does anyone have recommendations for doing this. Threejs to me a good candidate - a non React version, since it is a hierarchical system (scene, meshes, materials etc), but I suspect there are other applications.
I made an attempt to implement a Javascript version of Hickey's transducers - a sort of conveyor belt of functions and that is another instance of a series of processing steps that might be best represented in JSX
by andrewstuart on 8/17/24, 12:46 AM
<html lang="en">
<body>
<h1>Web Components Examples</h1>
<h2>Counter Component</h2>
<counter-component></counter-component>
<h2>Clickable Button Component</h2>
<clickable-button></clickable-button>
<h2>Toggler Component</h2>
<toggler-component></toggler-component>
<script>
class CounterComponent extends HTMLElement {
constructor() {
super();
this.count = 0;
this.button = document.createElement('button');
this.button.textContent = this.count;
this.button.addEventListener('click', () => {
this.count++;
this.button.textContent = this.count;
});
this.attachShadow({ mode: 'open' }).appendChild(this.button);
}
}
class ClickableButton extends HTMLElement {
constructor() {
super();
this.clicked = false;
this.button = document.createElement('button');
this.button.textContent = "Click me!";
this.button.addEventListener('click', () => {
this.clicked = !this.clicked;
this.button.textContent = this.clicked ? "Clicked!" : "Click me!";
});
this.attachShadow({ mode: 'open' }).appendChild(this.button);
}
}
class TogglerComponent extends HTMLElement {
constructor() {
super();
this.on = false;
this.button = document.createElement('button');
this.button.textContent = "OFF";
this.button.addEventListener('click', () => {
this.on = !this.on;
this.button.textContent = this.on ? "ON" : "OFF";
});
this.attachShadow({ mode: 'open' }).appendChild(this.button);
}
}
customElements.define('counter-component', CounterComponent);
customElements.define('clickable-button', ClickableButton);
customElements.define('toggler-component', TogglerComponent);
</script>
</body>
</html>
by NohatCoder on 8/17/24, 6:16 PM
Mostly I just do Vanilla.js, but the vanilla DOM creation functions turn really verbose, I got tired of that and created this to cut back on code size and increase readability.
There are other libraries that do something similar, but in my own very biased opinion this is one of the better.
by cies on 8/17/24, 10:29 AM
It looks simpler at first glance/ to a untrained eye; but it's just adding complexity without really solving any problems.
I like approaches like Kotlinx.html, scalatags, Elm's HTML package or HtmlFlow. They are also abstractions, but they add typesafety that html-as-a-string does not offer. On top of that you get breakpoints, code completion, and you can keep working in one language.
by miika on 8/17/24, 7:05 AM
by spullara on 8/16/24, 10:43 PM
by arjvik on 8/16/24, 10:07 PM
by xwall on 8/17/24, 10:09 PM
ultimately go to react.dev because: "Maturing is realizing React is best"
by dqh on 8/17/24, 8:58 AM
It started as a static site generator but added a bunch of support for client JavaScript too.
by NaN1352 on 8/17/24, 10:27 AM
by waynenilsen on 8/16/24, 10:27 PM
by n3storm on 8/17/24, 9:31 AM
by cyanydeez on 8/17/24, 12:10 AM
by emadda on 8/17/24, 2:32 PM
I would guess there is more overhead in creating a dom element than a JS object (which JSX elements compile to).
by nf17 on 8/17/24, 9:46 PM
by nashashmi on 8/16/24, 10:56 PM
by NaN1352 on 8/17/24, 10:24 AM
by andruc on 8/17/24, 1:39 PM
by frabjoused on 8/17/24, 5:08 AM
by jwtorres on 8/17/24, 8:03 PM