Live data from Hacker News

What dif­fer­enti­ates front-end frame­works

themer.dev

221–230 of 256 posts

Re: What dif­fer­enti­ates front-end frame­works

#221

> To overcome the shortcomings of the default change detection paradigm, the Angular team is working on a new approach called Signals. Conceptually, signals are similar to Svelte stores (which we’ll get to later), and fundamentally, they solve the change detection problem the same way as React; the framework is taking control over the application’s state so that changes can be easily monitored and re-renders can be a…

> React diffs the state object when `setState` is called, determining which part of the DOM to update.

Er, what? That's not true at all, even for class-based components. `setState` merely queues up another render of the function and its children. There is no diffing, except for the new DOM returned against what is currently rendered.

Re: What dif­fer­enti­ates front-end frame­works

#222
post #193

Earlier quoted context omitted.

States are scoped to a component, how "every" component that get the prop update ?

If you pass a prop to a child component, it will update whenever you change state If two unrelated components are consuming the same context, it will update when that context updates. Using Zustand, there's virtually no overhead to this and it's extremely reactive

"If you pass a prop to a child component, it will update whenever you change state"

Well if you update a state, every children of your component is updated as well regardless of if they have a prop passed.

I know there are way to make react trully reactive like Valtio using proxy or maybe Zustand, but my point is that useState or useContext is not "reactive" at all, you must call a function to rerender the components.

Re: What dif­fer­enti­ates front-end frame­works

#223

Why can't we just use Model-View-Controller for change-detection? Views subscribe with the model to get notifications about changes to different "aspects" of the model. When they get a change-notification they update themselves by asking the model for its latest data for a given aspect.

Sounds simple, right? It fails horribly, because you lose control of how data flows through your application. One view triggers an update to a model, which will immediately trigger other views to render regardless of where they exist in the component hierarchy or whether there are more changes to make in tandem. This can cascade to other updates, and suddenly you're in a weird intermediate state caused by a race condition between two separate views that's incredibly difficult to debug.

The reason why solutions like React are so popular is because it radically simplifies state management: data flows in from the top of the component hierarchy down. When a component makes changes to state, those changes are queued up for the next consistent render loop, which ensures that nothing renders in an intermediate state. An entire class of bugs, gone.

Re: What dif­fer­enti­ates front-end frame­works

#224

Earlier quoted context omitted.

Thanks for the thoughtful response. It's interesting hearing from someone who actually likes Qt. I use both React and Qt/QML for work, and I have a hard time enjoying the Qt/QML work. Maybe I'm missing something or doing things wrong? That reloading tool is cool, though its not quite as useful as modern dev servers. It seems like this simply restarts the app on every change, but modern dev servers remember your state…

Perhaps your experience with QML would be more pleasant if you would write backend in Rust or Julia (my current choice). In Julia I find that it is particularly easy to iterate as it avoids any compilation step although that is not as smooth as using VS Code with hot reload on the side. There is also Felgo for reloading which I guess also preserves the state, but I have not tried it yet. One quite an advantage for QM…

I still don't get what advantage QML has over something like Svelte. Writing the QML backend with Rust would be nicer, but why wouldn't I just write my front end using Svelte/TypeScript with something like Tauri at that point? With statically typed languages you get autocomplete, more instant feedback, more editor integration for things like renaming functions variables, and the end result won't have type errors at runtime.

Felgo is what I was hoping for, good find! That covers one pain point, but there's still many, many more. QML does have a simple and great list of components to get started with, where as HTML and CSS have accumulated many years of cruft. But, that being said, aligning elements into rows and columns is easy using CSS flexbox[1]. Flexbox has the benefit of being much more versatile than QMLs layout tools as well. I imagine using flexbox you could make the Kanban UI just as easily, and you'll probably run into less limitations.

[1] https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layou...

Re: What dif­fer­enti­ates front-end frame­works

#225
post #205

Earlier quoted context omitted.

Adding "declaratively" doesn't make it true either. You can declaratively pass objects between web components in every web components library out there like Lit or Stencil. Now, you may claim that that doesn't count because the declarative part is implemented in non-standard userland libraries, to which I would reply: 1) So what? React is a non-standard userland library. You can't pass data declaratively between Reac…

> You can declaratively pass objects between web components in every web components library out there like Lit or Stencil. This makes it a non-standard library-specific method of passing things. I have no idea what you're arguing against. There's literally no way to pass objects as attributes to web components. Web components had a great opportunity to get rid of attributes/properties dichotomy, but they doubled down…

> Of course there's nothing standardised, and nothing interoperable.

This is so very much not true. On what basis do you even claim this?

Web components are JavaScript objects that extend from HTMLElement. They all share a common interface of attributes, children, events and properties.

You can get a reference to any web components any set a property on it:

    document.querySelector('my-element').someProp = {};
This works on all web components. It's interoperable because there's no special React, or Angular, or Vue version of an API to set properties.

> There's literally no way to pass objects as attributes to web components

How do you even get a reference to an object in HTML to pass as an attribute, if you could?

And who cares? You can pass objects as properties to web components. Attributes are string-valued, why would you want to pass an object to them?

Re: What dif­fer­enti­ates front-end frame­works

#226

Earlier quoted context omitted.

Thanks for the thoughtful response. It's interesting hearing from someone who actually likes Qt. I use both React and Qt/QML for work, and I have a hard time enjoying the Qt/QML work. Maybe I'm missing something or doing things wrong? That reloading tool is cool, though its not quite as useful as modern dev servers. It seems like this simply restarts the app on every change, but modern dev servers remember your state…

Thanks for the kind words! > Maybe I'm missing something or doing things wrong? To be fair, I have many annoyances with Qt Quick. I think many of the components don't look and work native out of the box, requiring significant customization that is time-consuming compared to what you get out of the box by using many libraries alongside React. And there are these other annoyances that we already talked about. But in my…

> But in my view, the QML paradigm is extremely consistent, even migrating from Qt5 to Qt6 was quite straightforward. I just updated my website to a new NextJS version and so many things broke in React there were serious paradigm changes if I remember correctly.

Totally fair points here. Though slight nitpicks, these breaking changes were probably entirely NextJS changes and not React changes. NextJS solves a much more complicated problem, full stack web apps. I think it's more fair to compare QML with React as they both focus on simply describing UI.

> I appreciate the native performance I get from compiled C++ code (Most QML code is compiled to C++)[1]

I read the article and I'm skeptical that most QML code is compiled to C++. My understanding from the article is that they are able to compile VERY basic QML code that you manually specify all the types for. The problem still remains that QMLScript is a very dynamic language. QML doesn't even allow you to type your list or object properties! How much of your QML code doesn't touch lists or objects?

> But I'm not sure how QML is unsafe.

QML is unsafe because it's a dynamically typed langauges. Many errors will not be discovered until runtime! I brought your example over to qmlonline[1] and modified it.

  Rectangle {
      property int count: 0
      
      Button { onClicked: { count += "1"; } }
      
      Text { text: count.toString(); }
  }
This "compiles" fine, runs fine. In fact, it perceives this as fine behavior and continues on without even giving a runtime error when I click the button??

Let's try something even more clearly bad. Let's do `count = "test"`. This "compiles" and starts just fine too?? Finally you get a runtime error when you actually press the button.

I'm really skeptical about how or what C++ this all compiles too, because this is all very much dynamic behavior, and it's not giving us any useful feedback at compile time. These are really simple errors that this "QML compiler" should be catching and presenting to the developer.

These kind of errors are impossible with TypeScript. TypeScript will tell you immediately in your editor when you type this mistake, so you will never get runtime type errors. Going from TypeScript to QMLScript or regular JavaScript is probably the biggest downgrade of all to me. C++ is statically typed thankfully, but what good is having only half of your code statically typed?

> I like React for small projects but as it gets bigger I find it quite cumbersome.

Reading this and "developing in React always felt hacky like using duct tape and glue", I wonder how much of this is actually React and how much is using dynamic JavaScript. If your whole app was dynamic QML code, you'd probably feel like that was hacky too, right? If you have specific examples of things that felt hacky and hard in bigger projects, I'd love to hear that. My hypothesis is that you'd feel like your React projects were much more "solid" and "proper" if you used TypeScript. The facts are that your users would run into much less runtime errors with TypeScript code than C++/QMLScript code. Also, TypeScript provides much more immediate feedback while developing.

I'm curious about what you think QML really excels at. It sounds like it was perfect for quickly making a Kanban prototype? What all did the prototype include? Maybe I should try recreating some portion of it with Svelte. I think it could be interesting to have a direct comparison. If QML has useful tools for building UI that Svelte doesn't, I'd find that really interesting. I'm constantly looking for the best way to build UIs, and right now Svelte seems like the best.

If you remember the specific problem with Tauri, I'd be interested in hearing that. I'm curious about the performance differences between Tauri and Qt apps. There are probably some pros and cons with Tauri's web view approach. I imagine OS native web views might be better at rendering certain UIs than Qt's rendering.

It's cool that you're looking into Rust things too. Rust gives even better compile time feedback than TypeScript which excites me. It's super interesting hearing all your thoughts, and would love to hear more.

[1] https://qmlonline.kde.org/

Re: What dif­fer­enti­ates front-end frame­works

#227

Earlier quoted context omitted.

Perhaps your experience with QML would be more pleasant if you would write backend in Rust or Julia (my current choice). In Julia I find that it is particularly easy to iterate as it avoids any compilation step although that is not as smooth as using VS Code with hot reload on the side. There is also Felgo for reloading which I guess also preserves the state, but I have not tried it yet. One quite an advantage for QM…

I still don't get what advantage QML has over something like Svelte. Writing the QML backend with Rust would be nicer, but why wouldn't I just write my front end using Svelte/TypeScript with something like Tauri at that point? With statically typed languages you get autocomplete, more instant feedback, more editor integration for things like renaming functions variables, and the end result won't have type errors at r…

The flexbox does not seem to match the power of QML. For instance, I can have a two-pane view as simple as:

Text {

    anchors.top : parent.top

    anchors.bottom : parent.bottom

    anchors.left : parent.horizontalCenter

    anchors.right : parent.right

    anchors.topMargin : 10

    text : "Hello World"
}

which does not reference any dimensions of the objects. It is easy to reference an anchor of a sibling and other parent elements when needed.

Also, making new components is easy; I can inherit properties of a parent element, add my properties and put them in a file for later reuse is something I use extensively. Building each component carelessly using whatever mockery to get the look I need and then isolating it with its own namespace is relieving.

Re: What dif­fer­enti­ates front-end frame­works

#228

Why can't we just use Model-View-Controller for change-detection? Views subscribe with the model to get notifications about changes to different "aspects" of the model. When they get a change-notification they update themselves by asking the model for its latest data for a given aspect.

Sounds simple, right? It fails horribly, because you lose control of how data flows through your application. One view triggers an update to a model, which will immediately trigger other views to render regardless of where they exist in the component hierarchy or whether there are more changes to make in tandem. This can cascade to other updates, and suddenly you're in a weird intermediate state caused by a race cond…

> One view triggers an update to a model,

I think it should be only the Controller which changes the Model. That can cause views which are dependent on the "aspect" of the model that was changed to update themselves.

But a view updating itself should NOT cause the model to change and thus not cause a cascade of other views causing other views to change.

Re: What dif­fer­enti­ates front-end frame­works

#229

Earlier quoted context omitted.

Sounds simple, right? It fails horribly, because you lose control of how data flows through your application. One view triggers an update to a model, which will immediately trigger other views to render regardless of where they exist in the component hierarchy or whether there are more changes to make in tandem. This can cascade to other updates, and suddenly you're in a weird intermediate state caused by a race cond…

> One view triggers an update to a model, I think it should be only the Controller which changes the Model. That can cause views which are dependent on the "aspect" of the model that was changed to update themselves. But a view updating itself should NOT cause the model to change and thus not cause a cascade of other views causing other views to change.

That's still a problem, because a view can trigger multiple controller updates (perhaps across controllers!), which need to be batched so that the application data remains in a consistent state.

Re: What dif­fer­enti­ates front-end frame­works

#230

Earlier quoted context omitted.

I still don't get what advantage QML has over something like Svelte. Writing the QML backend with Rust would be nicer, but why wouldn't I just write my front end using Svelte/TypeScript with something like Tauri at that point? With statically typed languages you get autocomplete, more instant feedback, more editor integration for things like renaming functions variables, and the end result won't have type errors at r…

The flexbox does not seem to match the power of QML. For instance, I can have a two-pane view as simple as: Text { anchors.top : parent.top anchors.bottom : parent.bottom anchors.left : parent.horizontalCenter anchors.right : parent.right anchors.topMargin : 10 text : "Hello World" } which does not reference any dimensions of the objects. It is easy to reference an anchor of a sibling and other parent elements when n…

Thanks for the nice response!

> The flexbox does not seem to match the power of QML. For instance, I can have a two-pane view as simple as:

I'm a bit confused by this example. When you make the other pane wouldn't you need to define all of its anchors too? It seems like the more standard QML approach to a two-pane is using RowLayout[1].

  RowLayout {
      anchors.fill: parent
      Rectangle {
          Layout.fillWidth: true
          Text {
            text: "pane 1"
          }
      }
      Rectangle {
          Layout.fillWidth: true
          Text {
              text: "pane 2"
          }
      }
  }
I agree this is pretty nice and intuitive, but flexbox makes this problem easy too.

  
    pane 1

pane 2

Yes inline css has problems, but I didn't want to scare you away with Tailwind[2] and I think inlined CSS makes this example clearer.

> It is easy to reference an anchor of a sibling and other parent elements when needed.

It seems like by composing layouts in QML you can avoid a lot of manual anchor setting. Though layouts do have their limits. Is that why you resort to setting anchors manually? Flexbox is much less limited and flexbox layouts compose really well.

Do you have examples of UI layouts you feel QML solves intuitively that flexbox can't solve intuitively?

> Also, making new components is easy; I can inherit properties of a parent element, add my properties and put them in a file for later reuse is something I use extensively

Svelte works the same exact way. Well, except for the part that new components do not inherit from existing components. Svelte and other modern UI frameworks prefer composition over inheritance[3]. Composition allows you to be just as expressive, but without the footguns of inheritance. If you have a specific UI problem you think inheritance solves well, I'd be happy to try and create a matching composition based solution.

> Building each component carelessly using whatever mockery to get the look I need and then isolating it with its own namespace is relieving.

Svelte uses file based components as well. Each file is its own module in TypeScript/JavaScript.

If you have rebuttals or other additional things to add I'd love to hear it!

[1] https://doc.qt.io/qt-6/qml-qtquick-layouts-rowlayout.html

[2] https://tailwindcss.com/

[3] https://en.wikipedia.org/wiki/Composition_over_inheritance

Post reply on HN