                                     (get-node-id new-elem) state)
         state))))
 
+(defn- get-state-attr [state attr-str]
+  (when-let [attrs (when state (.-attrs state))]
+    (aget attrs attr-str)))
+
 (defn- on-attached [state node]
-  (when state
-    (when-let [node-attached (aget state "node-on-attached")]
-      (node-attached node))))
+  (when-let [node-attached (get-state-attr state "node/on-attached")]
+    (node-attached node)))
 
 (defn- replace-node-completely [parent new-elem-spec cur-dom-node top-level]
   (let [new-elem

        (.removeAttribute element attr-name)))))

(defn- bind-lifecycle-callback! [node node-state cb-name cb-value]
  (if (identical? cb-name "disposed")
    (set! (.-disposed-callback node-state) cb-value)
    (aset node-state (str "node-" cb-name) cb-value)))

(def ^:private attr-ns-lookup
  #js
  {:node bind-lifecycle-callback!})

(defn register-attr-prefix! [prefix xml-ns-or-handler]
  (aset attr-ns-lookup prefix xml-ns-or-handler))

              (when-not (.-disposed state)
                (let [new-elem (get-new-elem)
                      cur (.-cur-element state)
                      node-state (get-element-state cur)]
                  (when-not (identical? (get-virtual-dom cur) (get-virtual-dom new-elem))
                    (if-let [hide (get-state-attr node-state "node/on-detaching")]
                      (hide cur
                            (fn []
                              (if (.-disposed state)
