   (:require
     [cljsjs.react]
     [cljsjs.react.dom]
+    [goog :as goog]
+    [goog.object :as gobj]
     [sablono.core]
     [rum.cursor :as cursor]
     [rum.util :as util :refer [collect collect* call-all]]

           (fn [next-props next-state]
             (this-as this
               (let [old-state @(state this)
                     new-state @(aget next-state ":rum/state")]
                 (or (some #(% old-state new-state) should-update) false)))))
         :componentWillUpdate
         (when-not (empty? will-update)
           (fn [_ next-state]
             (this-as this
               (let [new-state (aget next-state ":rum/state")]
                 (vswap! new-state call-all will-update)))))
         :render
         (fn []

                                  :after-render] mixins)    ;; state -> state
        will-unmount   (collect   :will-unmount mixins)     ;; state -> state
        child-context  (collect   :child-context mixins)    ;; state -> child-context
        class-props    (reduce merge (collect :class-properties mixins)) ;; custom properties and methods

        ctor (fn [props]
               (this-as this
                 (set! (.-state this)
                       #js {":rum/state"
                            (-> (gobj/get props ":rum/initial-state")
                                (assoc :rum/react-component this)
                                (call-all init props)
                                volatile!)})
                 (.call js/React.Component this props)))]

    (gobj/set ctor "displayName" display-name)
    (goog/inherits ctor js/React.Component)

    (-> {:componentWillMount
         (when-not (empty? will-mount)
           (fn []
             (this-as this
