>it relies on memoization to preserve hidden state
It relies on the DOM to keep that state. It's not hidden, you are just not forced to deal with it or think about it.
>If you change the tree structure [...] and don't give scrollable UI items a key if they move, React will delete the scrollable DOM element [...]
Yes, if you have an array of elements, you need to give them a unique identifier. This is a fundamental property of any diff-algorithm which the virtual DOM relies on. I don't think that is unreasonable, and IMO it is not something that adds significant cognitive load.
React definitely has quirks and especially optimizing for performance can be quite complex. But out of all the GUI frameworks I have tried (including Win32, WinForms and GTK as well as other web ones), React is the most intuitive to me.
I think it's a leaky abstraction nonetheless, regardless if it causes issues in practice. But if it's not a significant issue to users, that's fine; personally I'd prefer to work in UI frameworks that avoid redundant diffing work by design (outside of cases like lists where it's difficult to avoid).
The abstraction is intentionally leak to meet a very valuable design goal: React plays well with other libraries that are manipulating the dom. This is a hard requirement for many businesses because libraries written without React in mind would often cost years to replicate.
So far as I can tell there's no reason someone couldn't apply the general approach to UIs React takes while also making it a less leaky abstraction. In a native scenario this makes a lot more sense because there's less components you might want to reuse vs the web.
If leaky abstractions are unavoidable, we're left with debates about which leaky abstractions are justifiable given the constraints and goals of the design.