               (gobject/extend
                 element-props
                 (.-props this)
-                #js {:value    (or (aget (.-state this) "state_value") js/undefined)
-                     :onChange (aget this "onChange")
+                #js {:onChange (aget this "onChange")
                      :children (aget (.-props this) "children")})
+              (aset element-props property (aget (.-state this) "state_value"))
               (js/React.createElement element element-props))))})))
 
-#?(:cljs (def wrapped-input (wrap-form-element "input")))
-#?(:cljs (def wrapped-select (wrap-form-element "select")))
-#?(:cljs (def wrapped-textarea (wrap-form-element "textarea")))
+#?(:cljs (def wrapped-input    (wrap-form-element "input"    "value" str)))
+#?(:cljs (def wrapped-checked  (wrap-form-element "input"    "checked" boolean)))
+#?(:cljs (def wrapped-select   (wrap-form-element "select"   "value" str)))
+#?(:cljs (def wrapped-textarea (wrap-form-element "textarea" "value" str)))
+
+#?(:cljs
+    (defn defined? [x]
+      (and (not (nil? x))
+           (not (undefined? x)))))
 
 #?(:cljs
    (defn create-element [type props & children]
-     (let [class (case (keyword type)
-                   :input
-                   (if (and props (or (exists? (.-checked props))
-                                      (exists? (.-value props))))
-                     wrapped-input "input")
-                   :select
-                   (if (and props (exists? (.-value props)))
-                     wrapped-select "select")
-                   :textarea
-                   (if (and props (exists? (.-value props)))
-                     wrapped-textarea "textarea")
-                   (name type))
+     (let [class (or (when (some? props)
+                       (case (name type)
+                         "input"
+                         (case (.-type props)
+                           "radio"    (when (defined? (.-checked props)) wrapped-checked)
+                           "checkbox" (when (defined? (.-checked props)) wrapped-checked)
+                           #_else     (when (defined? (.-value props)) wrapped-input))
+                         "select"     (when (defined? (.-value props)) wrapped-select)
+                         "textarea"   (when (defined? (.-value props)) wrapped-textarea)
+                         #_else       nil))
+                     (name type))
            children (remove nil? children)]
+       ;; React does not allow for value/checked to be nil, only js/undefined
+       (when (some? props)
+         (when (nil? (.-value props))
+           (set! (.-value props) js/undefined))
+         (when (nil? (.-checked props))
+           (set! (.-checked props) js/undefined)))
        (if (empty? children)
          (js/React.createElement class props)
          (apply js/React.createElement class props children)))))

;; waiting for requestAnimationFrame

#?(:cljs
   (defn wrap-form-element [element]
     (js/React.createClass
       #js
       {:displayName (str "wrapped-" element)
        :getInitialState
        (fn []
          (this-as this
            #js {"state_value" (aget (.-props this) "value")}))
        :onChange
        (fn [e]
          (this-as this
            (let [handler (aget (.-props this) "onChange")]
              (when-not (nil? handler)
                (handler e)
                (.setState this #js {"state_value" (.. e -target -value)})))))
        :componentWillReceiveProps
        (fn [new-props]
          (this-as this
            (let [state-value   (aget (.-state this) "state_value")
                  element       (js/ReactDOM.findDOMNode this)
                  element-value (.-value element)]
              ;; on IE, onChange event might come after actual value of an element
              ;; have changed. We detect this and render element as-is, hoping that
              ;; next onChange will eventually come and bring our modifications anyways.

              ;; https://github.com/tonsky/rum/issues/86
              (if (not= state-value element-value)
                (.setState this #js {"state_value" element-value})
                (.setState this #js {"state_value" (coerce (aget new-props property))})))))
        :render
        (fn []
          (this-as this
