Why do modern JavaScript Frameworks discourage direct interaction with the DOM

  • A+

In dealing with JS frameworks like AngularJS, Angular, and React, I've observed that directly interacting with the DOM is discouraged, and can often lead to bugs, if you ignore the warnings. When I say "interacting with the DOM" I mean using document.getElementById('myElement') and similar methods to do some manipulation or read values from the document.

My question is essentially Why?. Is this a virtual DOM problem, where React (for example) isn't tracking the actual DOM, and therefore will be caught off guard if you make a change "on your own" without notifying React and subsequently updating the virtual DOM? Would Angular have the same problem in such a case?

If someone has knowledge of only a specific framework, I would be very interested to read the answer to my question even if it is not generalized. Obviously, I'm going to go google this some more, but I didn't see a similar question here yet, so I figured I'd post for posterity. Thanks in advance for any insights!


@HDJEMAI linked to this article which I'll repeat, as it's good advice: https://www.reddit.com/r/javascript/comments/6btma7/whats_so_wrong_with_direct_dom_manipulation/

I'll expand on some of those reasons below:

  • Modern frameworks like Angular and React are designed to hide the DOM because they want to abstract the DOM away. By using the DOM directly you break the abstraction and make your code brittle to changes introduced in the framework.
  • There are many reasons to want to abstract-away the DOM, and the Reddit page linked-to mostly focuses on "state management" because your framework (Angular, React, etc) will likely make assumptions about the DOM's state that will be broken if you manipulate the DOM directly, for example:

    function this_is_your_code() {      tell_angular_to_make_my_sidebar_500px_wide();      document.getElementById('mysidebar').style.width = 700px;      var sidebar_width = ask_angular_for_sidebar_width();     console.log( sidebar_width ); // will print "500px" } 
  • Another reason to abstract away the DOM is to ensure your code works with non-traditional DOMs besides the typical web-browser document/window DOM environment, for example "server-side Angular" is a thing, where some of the Angular code runs on the server to pre-render HTML to send to the client to minimize application startup delay or to allow web-browsers without JavaScript to access your webpages, in these situations the normal W3C DOM is no-longer available, but a "fake" DOM is available but it's provided by Angular - and it only works through Angular's abstractions - it won't work if you manipulate document directly, for example:

    function this_is_your_code_that_runs_in_nodejs() {      tell_angular_to_make_my_sidebar_500px_wide(); // this works and Angular's built-in abstraction of the DOM makes the appropriate change to the rendered server-side HTML      document.getElementById('mysidebar').style.width = 500px; // fails because `document` is not available } 


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: