Declarative is a vacuous word that means anything you want it to depending on context. We used to call functional programming "functional" and logic programming languages like Prolog "declarative." Then declarative started meaning markup, then declarative started meaning...immutable functional code? In PL, we mostly just avoid the word altogether these days since everyone has a different idea about what it means.
React is closer to an immediate-mode UI model: you write programs that compute exactly what the UI should look like on each frame, rather than mutating a scene graph each time something interesting happens (as occurs in retained-mode UI models). Substitute DOM for scene graph, and the distinction might hold.
I think that the reason people started calling React 'declarative' was because 'functional' was interpreted to mean (purely) functional, with no side effects.
But yes, exactly. React is similar to an immediate mode graphics API. Except that also has weird connotations, because people think of things like canvas that are very low-level: all you get are lines, arcs, and fills. React's primitives are at the same level of abstraction as the DOM, you just work with them in immediate mode, not retained mode.
If I understand correctly, the DOM is retained, and React brings abstracts it efficiently back to a immediate mode API with some state retention, which has benefits since things stay consistent automatically.
In contrast, a UI model like WPF uses (declarative) data binding to achieve something similar, but without as much flexibility and with more verbosity.
I'm working on a system that allows for state retention in an immediate mode model, though wrapping WPF rather than HTML:
React is closer to an immediate-mode UI model: you write programs that compute exactly what the UI should look like on each frame, rather than mutating a scene graph each time something interesting happens (as occurs in retained-mode UI models). Substitute DOM for scene graph, and the distinction might hold.
But I'm not sure.