Live data from Hacker News

JavaScript Views, the Hard Way – A Pattern for Writing UI

github.com

61–70 of 141 posts

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#61
post #44
post #42

People like to hate on PHP, but PHP provides you with all the tools you need to write a fully working backend, where as JS provides you with half-assed solutions for writing frontend, which is why we have 1000 frameworks and we still can't agree on how to write frontend code. Seriously, we don't even have a convention for writing a simple reusable component with vanilla JS, everyone makes up their own thing. Web comp…

That is why I made my peace with Next.js. It is the only framework that feels like I am using JSP, JSF, ASP.NET, Spring, Quarkus, PHP. Don't plan to use anything else in JS space, unless by external decisions not under my control.

While I chafe at some of its decisions, you're still correct. It's the only thing really in that space that's fully featured enough.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#62
post #9

Earlier quoted context omitted.

How do you update the html when something changes? For me, that's the most interesting question for these sorts of micro-frameworks - templating HTML or DOM nodes is super easy, but managing state and updates is hard.

I call printPosts with the new post data. It rewrites the whole chunk in one go, which is pretty snappy. I haven't decided how I'm going to handle more granular updates yet, like comment count or likes.

Yeah, that's a pretty common approach. Unfortunately, browsers aren't very good at doing patch updates, so it'll completely reset any UI elements in the region being rerendered.

It also will make it hard to scope anything you want to do to an individual DOM element. If you want granular updates, for example, you want to be able to do something like `document.querySelector(???)` and be certain it's going to refer to, say, a specific text input in your `printPost` template, without worrying about accessing the inputs created by other instances of the `printPost` template. You can do that with unique IDs, but it's fiddly and error-prone.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#63
post #54

Earlier quoted context omitted.

The problem the name will have to be updated in 6 places in the UI.

1. Then add the 6 updates to the "setter" function 2. What UI has the same data presented 6 times? Seems unnecessary

A lot of UIs have redundant data, it's very common to have the same data represented in different ways. Consider the comments page on HN, for example, which has plenty of duplicate information:

The list of comments on a submission tells you how many comments exist, but the comment count is also made explicit at the top of the page directly underneath the submission title.

If one person comments multiple times, their user name will appear multiple times on the page, despite being the same every time.

All the timestamps are presented as relative timestamps, which means they're all dependent on the current time.

Now this is a very simple page, and it's not so important that everything be updated live. But if it were, you'd need to update every single timestamp on the page, keep all of the usernames in sync in case a user changed their name, insert new comments while also updating the comment count, etc. There is a lot of redundancy in most UIs.

In fact, I vaguely remember one of the early React blog posts using a very similar example (I think something to do with Messenger?) to explain the benefits of having a data-driven framework rather than using the DOM as the source of truth for data. For a messaging application, it's much more important that everything be live, and that elements don't end up out-of-sync.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#64
post #8

It appears to be exactly the kind of manual-update code that reactive view libraries exist to replace.

It’s probably about time for that to become fashionable again

Do you mean subscribing to events/callbacks, manually managing object lifecycle, manually inserting list elements, keeping it in sync with the state, etc, etc. Because that was all friggen horrible. Maybe new approaches could make it less horrible, but there is no way I’d go back to what it was like before React. If anything, I want everything to be more reactive, more like immediate mode rendering.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#65
post #46

Earlier quoted context omitted.

IIRC its what frameworks like Svelte do when they hit the compiler and optimize, which makes the best of both worlds.

They still nail "state" to element trees, which creates unbenchmarkable but real update costs. Svelte does better than react, but only within the same paradigm.

Can you describe what you mean by that a bit more? As I understand it, with the new signals-based system in Svelte, updating data directly updates the DOM.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#66

This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern. I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required. So instead of: /* State variables */ let name; /* DOM update functions */ function setNameNode(value) { nameNode.textContent =…

> use the DOM element value/textContent/checked/etc as the only source of truth How do you manage redundant state? For example a list with a "select all" button, then the state "all selected"/"some selected"/"none selected" would be duplicated between the "select all" button and the list of elements to select. This is the fundamental (hard) problem that state management needs to solve, and your proposal (along with t…

That is just select with multi. And one can also have class vs id.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#67
post #8

It appears to be exactly the kind of manual-update code that reactive view libraries exist to replace.

It’s probably about time for that to become fashionable again

It's easy to forget how tedious things used to be before React became popular.

Keeping data in sync with the UI was a huge mental burden even with relatively simple UIs. I have no desire to go back to that.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#68

This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern. I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required. So instead of: /* State variables */ let name; /* DOM update functions */ function setNameNode(value) { nameNode.textContent =…

> (...) I think 'state' variables are an anti-pattern. I use webcomponents (...) It's unclear what you mean by "state variables". The alternative to state variables you're proposing with webcomponents are essentially component-specific state variables, but you're restricting their application to only cover component state instead of application state, and needlessly restricts implementations by making webcomponents m…

"State variables" is a section in the original article. It shows a variable in the view, "name", that holds the value separate from the DOM.

setName(value) first checks the local state variable, and if different the value is both written to the state variable and the DOM.

The GP's pattern uses getters and setters to directly read and write to the DOM, skipping the need for a local variable entirely.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#69

This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern. I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required. So instead of: /* State variables */ let name; /* DOM update functions */ function setNameNode(value) { nameNode.textContent =…

I love the idea of a single source of truth. However, how does your approach handle browsers / plugins that modify the dom? For example, I can imagine Google Translate altering the textContent and some resulting downstream effects on business logic.

If the view needs to react to the updated DOM you could use a custom element and the attribute changed callback. If you don't need to react to if the updated text content would just be there the next time the view needs to read it.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#70

This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern. I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required. So instead of: /* State variables */ let name; /* DOM update functions */ function setNameNode(value) { nameNode.textContent =…

This was my first thought as well. I like the convention the OP is proposing here, with this one tweak making the DOM the single source of truth rather than local state inside views or components.

Hell, even in react I try to follow a similar pattern as much as possible. I'll avoid hooks and local state as much as possible, using react like the early days where I pass in props, listen to events, and render DOM.

Post reply on HN