I was thinking about how I’d answer one of our interview questions: “What are the benefits of React?” I feel like most of the usual answers here are not relevant.
If we can winnow out one benefit of React, it would be the ability to express a direct functional relationship between state and DOM, as opposed to worrying about how changes in state lead to changes in DOM. Render functions are passed updated values of state, spit out a new chunk of virtual DOM, and React (heuristically) figures out what bits of the actual DOM need to be updated. Basically, React is doing the “numerical derivative” of the render function. Previous approaches a la jQuery were really attempts at directly coding the “analytical” derivative of the render function, directly mapping state changes to DOM changes, which is clearly going to be nightmarishly complex for anything but the simplest state->DOM mappings.
But virtual-DOM diffing is not the only approach, and arguably not even the best one. React (and all virtual DOM frameworks) use heuristics to approximate the diff, because doing a full exact difference between two trees is really expensive (O(n³), where n is the number of elements in the tree). React’s heuristics run in O(n). Direct reactive binding, however, is effectively O(1) (-ish, really scales as the number of binding changes). Consider the approach taken by fReactive. Looking at render functions for something like om-next compared to fReactive, there is little difference, mainly the explicit dereferencing of state variables in fReactive (that difference gets even smaller when compared with Reagent). The implementation, however, is vastly different. The “render function” for fReactive is called once to establish bindings between those explicitly deref’ed variables and DOM elements and attributes. Thereafter, changes to the variables propagate directly to changes in the DOM, no middle-man virtual DOM manipulation required.
So why has virtual DOM and all of the diff complexity won the day? Part of the answer may be the implied architecture. The virtual DOM approach, for whatever reason, seems to have inspired some reasonable architectural approaches for managing the complexity of application state updates. Reactive approaches seem to be viral, encouraging reactive programming everywhere. That was certainly the case with fReactive, leading to a complection of different concerns and code that was extremely hard to debug, once you moved past very basic applications. You could, of course, meld the state management approaches inspired by virtual DOM with the direct binding DOM update, perhaps worth thinking about. It maybe just hasn’t occurred because for whatever reason the virtual DOM approach puts you in a different head-space than reactive when thinking about state. But it technically seems feasible.
But all of this skates around the real issue: the DOM sucks for applications. Markup languages like HTML are great for making documents, where the tree structure of the language maps directly the the semantic and visual structure of the document. And while pieces of application may be effectively rendered in document form, as markup, certainly the larger structure of application UI is not well-represented by markup. Think about something as simple as a modal dialog: the content is probably nicely rendered via markup. But where the hell does the dialog “element” go within the global HTML tree? And what does it’s position in that tree “mean”? It certainly means nothing visually, but perhaps somehow pollutes how events are propagated, etc. The whole thing is gross. HTML was originally intended as a way of rendering scientific papers online. Its use for applications is simply due to the ubuiquity of web browsers as an interface. Attempts to improve or replace HTML, such as XAML, have been abject failures, not because HTML was superior, but because the epic suckitude of markup for applications becomes all that more obvious when having to learn a new tech from scratch. Everybody is inured to the warts of HTML. Tools like React which ease some of that pain are thus viewed as “solutions”.
Perhaps it’s time to examine the problem from the other direction. Rather than starting with HTML and trying to figure out how to minimize the resulting headaches, we should independently consider how best to represent application UI. Particular attention should be given to the problem of transforming application state changes into UI state changes, minimizing the complexity of calculating the “derivative” of the render function. That leads us to consider how best to represent the relationships between visual elements. HTML largely tries to express those relationships as hierarchy and ordering, but a more explicit and mathematical model will likely simplify how state transforms to UI. From these requirements, we can always work out how to transform this more natural representation to the DOM.