     (not (util/equal-args a1 a2))))
 
 (defn wrap-component [comp extras]
-  (let [spec #js {:render #(this-as C (wrapped-render C comp extras))
-                  :shouldComponentUpdate
-                  #(this-as C (wrapped-should-update C %1 %2))}]
-    (.createClass React spec)))
+  (.createClass React (js-obj "render"
+                              #(this-as C (wrapped-render C comp extras))
+                              "shouldComponentUpdate"
+                              #(this-as C (wrapped-should-update C %1 %2)))))
 
 ;; From Weavejester's Hiccup, via pump:
-;; https://github.com/weavejester/hiccup/blob/master/src/hiccup/compiler.clj#L32
 (def ^{:doc "Regular expression that parses a CSS-style id and class
-             from a tag name."
-       :private true}
+             from a tag name."}
   re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")
 
 (def DOM (aget React "DOM"))

    (set! (.-cljsReactClass f) wrapf)
    wrapf))

(defn as-class [x]
  (cond
   (keyword? x) (cached-wrapper x)
   (not (nil? (.-cljsReactClass x))) (.-cljsReactClass x)
   :else (do (assert (fn? x))
             (if (.isValidClass React x)
               (set! (.-cljsReactClass x) (wrap-component x nil))
               (fn-to-class x)))))

(defn vec-to-comp [v]
  (assert (pos? (count v)))
  (let [[tag props] v
        c (as-class tag)
        obj (js-obj)]
    (set! (.-cljsArgs obj) v)
    (when (map? props)
      (let [key (:key props)]
        (when-not (nil? key)
          (set! (.-key obj) key))))
    (c obj)))

(defn as-component [x]
  (cond (vector? x) (vec-to-comp x)

        (ifn? val) (fn [& args] (apply val args))
        :else (clj->js val)))

(defn set-id-class [props [id class]]
  (aset props "id" id)
  (when class
    (aset props "className" (if-let [old (aget props "className")]
                              (str class " " old)
                              class))))

(defn convert-props [props id-class]
  (let [is-empty (empty? props)]
    (cond
     (and is-empty (nil? id-class)) nil
     (identical? (type props) js/Object) props
     :else (let [objprops (js-obj)]
             (when-not is-empty
               (doseq [[k v] props]
                 (aset objprops (cached-prop-name k)
                       (convert-prop-value v))))
             (when-not (nil? id-class)
               (set-id-class objprops id-class))
             objprops))))

(defn map-into-array [f coll]
  (let [a (into-array coll)]
    (dotimes [i (alength a)]
      (aset a i (f (aget a i))))
    a))

(declare as-component)

(defn wrapped-render [this comp id-class]
  (let [inprops (aget this "props")
        args (.-cljsArgs inprops)
        props (nth args 1 nil)
        hasprops (or (nil? props) (map? props))
        jsargs (->> (if hasprops (drop 1 args) args)
                    (map-into-array as-component))]
    (aset jsargs 0 (convert-props (if hasprops props) id-class))
    (.apply comp nil jsargs)))

(defn wrapped-should-update [C nextprops nextstate]
  (let [a1 (-> C (aget "props") .-cljsArgs)
