Live data from Hacker News

How UI-driven state increases accidental complexity

evgenii.info

41–50 of 51 posts

Re: How UI-driven state increases accidental complexity

#41
It's an interesting tension.

One reality is that you can model the domain really well, keep it decoupled from the UI, and be able to maintain the app for the long term. Unfortunately if you have any neurotypicals involved they are going to feel mentally and maybe even physically uncomfortable from the discipline and won't rest until it is all tangled up again.

Another approach is to make the system very shallow, design the data structures to represent the UI you want directly, and hopefully gain enough in simplicity that you can deal with long-term evolution in creative ways such as end-to-end versioning.

The difficulty of reconciling the two has been one of the problems with UML, RDF, Graph Viz, Low Code, etc.

Some of the description of a system is unrelated to how it is visualized, yet, if you don't support manual layout and routing the visualizations you make will be meaningless. (In 2020 people are still too polite to tell the makers of hairball graphs that they should go back to the drawing board, but in 2005 there was a "emperor's new clothes" phenomenon where people didn't trust their instincts -- at least now they'll be honest with somebody else.)

Re: How UI-driven state increases accidental complexity

#43
post #9

Earlier quoted context omitted.

Can you describe this implementation with just vanilla js? What’s the gist here, you’re using namespaced events? I’m just curious what this would look like outside of the world of React.

There are a lot of approaches you can take with vanilla js, but if your UI follows a component architecture that's modeled as a tree (App > Pages > Widgets), what I'm saying is that you take all of your interactive UI components and separate them into two nodes (a parent and a child). The parent P holds the state and provides callbacks to all descendants, one of which is the child C that you are writing. C is a pure…

[deleted]

Re: How UI-driven state increases accidental complexity

#44
post #2

The proposed approach is correct for the proposed use-case. The problem is, lots of UI state isn't handsome, core data like in this example. What about storing the width of a resizable panel? Or the state of a dropdown that can be open or closed? Do you create a dozen little flags in your store for these? Or do you put a flag on each domain object (todo list item, for example) that's not actually relevant to your bus…

https://github.com/janestreet/bonsai is making some interesting distinctions between "UI state" and "model state". They're kept separate and they're working on utilities to manage the use of composed components.

Re: How UI-driven state increases accidental complexity

#45
post #2

The proposed approach is correct for the proposed use-case. The problem is, lots of UI state isn't handsome, core data like in this example. What about storing the width of a resizable panel? Or the state of a dropdown that can be open or closed? Do you create a dozen little flags in your store for these? Or do you put a flag on each domain object (todo list item, for example) that's not actually relevant to your bus…

> but what happens when something else in your UI cares about it and has to respond to it?

HTML event-listeners like on-blur, on-focus, on-click, etc. handle this very nicely. I've found that they're frequently disregarded in component libraries, unfortunately.

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEvent...

Re: How UI-driven state increases accidental complexity

#46
post #39
post #24

Earlier quoted context omitted.

The original drop down can close itself when it loses focus. No need go into shared state for this usecase.

Losing focus is itself a stateful change on a UI element caused by another UI element. It's just that the frontend platform like the browser or OS manages that shared state for you.

Yes, this is key. There are many cases like this (and CSS pseudo-classes, and the drag and drop API, etc.) where the browser platform gives you convenient ways of avoiding the problem. And certainly, take advantage of those where possible. But they don't eliminate the problem in the general sense.

Re: How UI-driven state increases accidental complexity

#47
post #3
post #2

The proposed approach is correct for the proposed use-case. The problem is, lots of UI state isn't handsome, core data like in this example. What about storing the width of a resizable panel? Or the state of a dropdown that can be open or closed? Do you create a dozen little flags in your store for these? Or do you put a flag on each domain object (todo list item, for example) that's not actually relevant to your bus…

The way I handle this, at least in React, is to create a context provider that handles my component's view state, then write my UI element as a consumer of that view state by wrapping it in an HOC. Then, if any other component wants to subscribe to the particular user interaction that drives the component I'm writing, they can simply tap into the existing context with an HOC that I've already written for them. This w…

Do you have example code?

Re: How UI-driven state increases accidental complexity

#48

  In contrast, it doesn't happen with a denormalized, UI-agnostic state:
Isn't it the other way around? the UI-agnostic state IS the normalized version; the UI-aware state ready to be consumed is the denormalized one.

The choice is pretty simple to me: keep the State normalized, de-normalize it in selectors for consumption in the UI. Those selectors will look pretty much the same as the reducers you'd be writing anyway.

Re: How UI-driven state increases accidental complexity

#50

In contrast, it doesn't happen with a denormalized, UI-agnostic state: Isn't it the other way around? the UI-agnostic state IS the normalized version; the UI-aware state ready to be consumed is the denormalized one. The choice is pretty simple to me: keep the State normalized, de-normalize it in selectors for consumption in the UI. Those selectors will look pretty much the same as the reducers you'd be writing anyway…

Came just to post this. The state he's described is definitely normalized, and the UI-specific one is denormalized.

And I think your advice is exactly right: project your normalized state into a view that's useful for consumption by other components. Basically, the same pattern we've been applying to relational databases for decades.

Post reply on HN