Baby steps: So you want to wrap one fake reactive library with killer native support with a real reactive library? Before we clean it up with macrology, a Godsend in cases like this, we have:
(mxr/make-rnc ;; Matrix component constructor
{:counter (cI 42) ;; An "input" cell. We get to write to it from good old declarative code
:label (cF (str "The counter is at "
(mget me :counter))) ;; <<<--- The new count arrives automagically. No subscribe needed, just read the Cell.
:rendering (cFonce
($ (hx/fnc [] ;; Here we build an anonymous React component. Thanks, @lilactown!
(let [[_ set-state] (hooks/use-state 0)] ;; The React way of "watching" state
(mxr/set-state-record me set-state) ;; Store the setter function where we can find it
(d/button {:on-click #(mswap! me :counter inc)} {} ;; mswap! also triggers a dataflow event -->>>
(mget me :label))))))}) ;; <<<--- again, reading the value implicitly subscribes to it
(defmethod observe-by-type [::mxrn.elt] [slot me new-val prior-val cell] ;; <<<--- Matrix standard observer
((get @set-state-dict (mget me :sid)) (pulse-now))))) ;; <<<--- artificial call to React state hook to trigger refresh...Fini!
A true wrapping, even textually: everything inside ($ ....) is React, itself thinly wrapped by CLJS Helix, everything outside is Matrix.
Next up, Matrix + ReactNative.
React is awful, but FB pours a lot of money into the core DOM integration, and it is complete. Most important, they have wrapped Android and iOS with a common JS library. And Helix has created a JSX-free interface. Yay.