Live data from Hacker News

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

github.com

11–20 of 141 posts

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

#11

I came up with something similar recently, except it doesn't use template elements. It just uses functions and template literals. The function returns a string, which gets dumped into an existing element's innerHTML. Or, a new div element is created to dump it into. Re-rendering is pretty quick that way. A significant issue I have with writing code this way is that the functions nest and it becomes very difficult to…

I prefer something like this before building the template string.

image = post.image_urls?[0] || "";

Then have the printImage function return an empty string if the argument is an empty string.

${printImage(image)}

Easier on the eyes.

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

#12

I came up with something similar recently, except it doesn't use template elements. It just uses functions and template literals. The function returns a string, which gets dumped into an existing element's innerHTML. Or, a new div element is created to dump it into. Re-rendering is pretty quick that way. A significant issue I have with writing code this way is that the functions nest and it becomes very difficult to…

This is begging for injection attacks. In this case, for example, if parsed_text and filtered can contain Generating serialised HTML is a mug’s game when limited to JavaScript. Show me a mature code base where you have to remember to escape things, and I’ll show you a code base with multiple injection attacks.

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

#14
post #9

I came up with something similar recently, except it doesn't use template elements. It just uses functions and template literals. The function returns a string, which gets dumped into an existing element's innerHTML. Or, a new div element is created to dump it into. Re-rendering is pretty quick that way. A significant issue I have with writing code this way is that the functions nest and it becomes very difficult to…

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 find the coroutine/generator approach described in a series of posts by Lorenzo Fox/Laurent Renard to be a promising alternative[0].

It takes a little to wrap your head around, but essentially structures component rendering to follow the natural lifecycle of a generator function that takes as input the state of a previous yield, and can be automatically cleaned up by calling `finally` (you can observe to co-routine state update part in this notebook[1]).

This approach amounts to a really terse co-routine microframework [2].

[0]: https://lorenzofox.dev/posts/component-as-infinite-loop/#:~:...

[1]: https://observablehq.com/d/940d9b77de73e8d6

[2]: https://github.com/lorenzofox3/cofn

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

#15

I came up with something similar recently, except it doesn't use template elements. It just uses functions and template literals. The function returns a string, which gets dumped into an existing element's innerHTML. Or, a new div element is created to dump it into. Re-rendering is pretty quick that way. A significant issue I have with writing code this way is that the functions nest and it becomes very difficult to…

This is begging for injection attacks. In this case, for example, if parsed_text and filtered can contain Generating serialised HTML is a mug’s game when limited to JavaScript. Show me a mature code base where you have to remember to escape things, and I’ll show you a code base with multiple injection attacks.

Yeah, OPs code is asking for pain. I suspect there are now developers who've never had to generate html outside the confines of a framework and so are completely unaware of the kinds of attacks you need to protect yourself against.

You can do it from scratch, but you essentially need to track provenance of strings (either needs to be escaped and isn't html, e.g., user input, or html, which is either generated and with escaping already done or static code). It seems like you could build this reasonably simply by using tagged template literals and having e.g., two different Types of strings that are used to track provenance.

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

#17
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 = value;
  }

  /* State update functions */
  function setName(value) {
    if(name !== value) {
      name = value;
      setNameNode(value);
    }
  }

it would just be akin to:

  set name(name) { this.nameNode.textContent = name }
  get name() { return this.nameNode.textContent}

  /* or if the variable is used less than 3 times don't even add the set/get */ 
  setState({name}){
     this.querySelector('#name').textContent = name;
  }
Its hard to describe in a short comment, but a lot of things go right naturally with very few lines of code.

I've seen the history of this creating spaghetti, but now with WebComponents there is separation of objects + the adjacent HTML template, creating a granularity that its fusilli or macaroni.

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

#19

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 is what I did in jquery era and it works very well, since it seldom to have state management at that era. Sure there's data binding libs like backbonejs and knockoutjs for a more complex app, but this approach works well anyway.

Having a manual state that do not automatically sync to elements will only introduce an unnecessary complexity later on. Which is why libraries like react and vue works well, they automatically handle the sync of state to elements.

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

#20

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 don't think that is heresy, essentially you are describing what MUI calls unmanaged components - if I understand you well.

These have their places, but I don't see them as an either-or replacement for managed components with associated states.

Post reply on HN