In the end you want to write a function that just expresses what the state of the DOM should be depending on the input parameters and have something deal with applying those changes to a very stateful API. If the application state changes, all you want to do is say 'things have changed somehow, just re-render this component'.
This was possible before with classic templating, but it wasn't very efficient and had problems when dealing with re-rendering interactive elements. You would lose focus on input fields for example, and had to use some post-render hooks to fix the state of the DOM up afterwards.
Using virtual DOM structures fixed this problem in an elegant way and allowed rendering to the DOM to be integrated into more functional programming styles, which made more reactive architectures possible.
It all boils down to humans not being good with reasoning about state changes over time and how to express those imperatively. The only solution to that is not to do it and go more functional.
This is also why I am not a big fan of things like incremental-dom. It ignores the whole idea why we wanted declarative DOM handling in the first place and replaces it with a very imperative and side-effect heavy API. In that case, just use the DOM directly.