Permalink
Browse files

React 16 support

  • Loading branch information...
anmonteiro committed Sep 29, 2017
1 parent bc1c30f commit fa67729d71b845c31c9a59f1d3642a1c08e0d59f
Showing with 91 additions and 64 deletions.
  1. +2 −2 boot.properties
  2. +16 −11 build.boot
  3. +5 −5 pom.xml
  4. +5 −5 project.clj
  5. +3 −3 src/main/om/dom.cljc
  6. +55 −35 src/main/om/dom.cljs
  7. +5 −3 src/main/om/next.cljc
@@ -1,5 +1,5 @@
#http://boot-clj.com
#Fri Sep 02 22:34:38 WEST 2016
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_CLOJURE_VERSION=1.9.0-alpha16
BOOT_VERSION=2.7.1
BOOT_CLOJURE_VERSION=1.9.0-alpha19
BOOT_VERSION=2.7.2
@@ -1,17 +1,17 @@
(set-env!
:source-paths #{"src/main"}
:dependencies '[[org.clojure/clojure "1.9.0-alpha16" :scope "provided"]
[org.clojure/clojurescript "1.9.542" :scope "provided"
:dependencies '[[org.clojure/clojure "1.9.0-alpha19" :scope "provided"]
[org.clojure/clojurescript "1.9.908" :scope "provided"
:classifier "aot"
:exclusions [org.clojure/clojure
org.clojure/data.json]]
[org.clojure/clojurescript "1.9.542" :scope "provided"
[org.clojure/clojurescript "1.9.908" :scope "provided"
:exclusions [org.clojure/clojure
org.clojure/data.json]]
[org.clojure/data.json "0.2.6" :scope "provided"
:classifier "aot"]
[cljsjs/react "15.5.4-0"]
[cljsjs/react-dom "15.5.4-0"]
[cljsjs/react "16.0.0-0"]
[cljsjs/react-dom "16.0.0-0"]
[com.cognitect/transit-clj "0.8.300"]
[com.cognitect/transit-cljs "0.8.239"]
@@ -20,20 +20,20 @@
[figwheel-sidecar "0.5.10" :scope "test"
:exclusions [org.clojure/clojurescript
org.clojure/tools.reader]]
[devcards "0.2.3" :scope "test"
[devcards "0.2.4-SNAPSHOT" :scope "test"
:exclusions [org.clojure/clojurescript]]
[com.cemerick/piggieback "0.2.1" :scope "test"
:exclusions [org.clojure/clojure
org.clojure/tools.nrepl
org.clojure/clojurescript]]
[pandeiro/boot-http "0.8.3" :scope "test"]
[adzerk/boot-cljs "2.0.0" :scope "test"
[adzerk/boot-cljs "2.1.4" :scope "test"
:exclusions [org.clojure/clojurescript]]
[adzerk/boot-cljs-repl "0.3.3" :scope "test"]
[adzerk/boot-test "1.2.0" :scope "test"]
[crisptrutski/boot-cljs-test "0.3.0" :scope "test"
[crisptrutski/boot-cljs-test "0.3.4" :scope "test"
:exclusions [org.clojure/clojurescript]]
[adzerk/boot-reload "0.5.1" :scope "test"]
[adzerk/boot-reload "0.5.2" :scope "test"]
[org.clojure/tools.nrepl "0.2.13" :scope "test"]
[weasel "0.7.0" :scope "test"]]
:exclusions '[org.clojure/clojure org.clojure/clojurescript])
@@ -58,8 +58,10 @@
(reload)
(speak)
(cljs :source-map true
:optimizations :none
:compiler-options {:devcards true
:main 'om.devcards.core
:verbose true
:parallel-build true}
:ids #{"devcards/main"})
(target)))
@@ -84,8 +86,11 @@
(bct/test-cljs
:js-env :node
:namespaces #{'om.next.tests}
:cljs-opts {:parallel-build true}
:exit? exit?))))
:cljs-opts {:parallel-build true
:target :nodejs
:asset-path "test_suite.out"}
:exit? exit?
:ids #{"lumo_test/test_suite"}))))
(deftask test
[e exit? bool "Enable flag."]
10 pom.xml
@@ -63,13 +63,13 @@
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.9.0-alpha16</version>
<version>1.9.0-alpha19</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojurescript</artifactId>
<version>1.9.542</version>
<version>1.9.908</version>
<classifier>aot</classifier>
<scope>provided</scope>
<exclusions>
@@ -111,12 +111,12 @@
<dependency>
<groupId>cljsjs</groupId>
<artifactId>react</artifactId>
<version>15.5.4-0</version>
<version>16.0.0-0</version>
</dependency>
<dependency>
<groupId>cljsjs</groupId>
<artifactId>react-dom</artifactId>
<version>15.5.4-0</version>
<version>16.0.0-0</version>
</dependency>
<dependency>
<groupId>org.clojure</groupId>
@@ -143,7 +143,7 @@
<dependency>
<groupId>devcards</groupId>
<artifactId>devcards</artifactId>
<version>0.2.3</version>
<version>"0.2.4-SNAPSHOT"</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -10,13 +10,13 @@
:source-paths ["src/main" "src/devcards" "src/test"]
:dependencies [[org.clojure/clojure "1.9.0-alpha17" :scope "provided"]
[org.clojure/clojurescript "1.9.542" :scope "provided" :classifier "aot"
:dependencies [[org.clojure/clojure "1.9.0-alpha19" :scope "provided"]
[org.clojure/clojurescript "1.9.908" :scope "provided" :classifier "aot"
:exclusions [org.clojure/clojure
org.clojure/data.json]]
[org.clojure/data.json "0.2.6" :scope "provided" :classifier "aot"]
[cljsjs/react "15.5.4-0"]
[cljsjs/react-dom "15.5.4-0"]
[cljsjs/react "16.0.0-0"]
[cljsjs/react-dom "16.0.0-0"]
[com.cognitect/transit-clj "0.8.300"]
[com.cognitect/transit-cljs "0.8.239"]
@@ -25,7 +25,7 @@
[figwheel-sidecar "0.5.10" :scope "test"
:exclusions [org.clojure/clojurescript
org.clojure/tools.reader]]
[devcards "0.2.3" :scope "test"
[devcards "0.2.4-SNAPSHOT" :scope "test"
:exclusions [org.clojure/clojurescript]]]
:plugins [[lein-cljsbuild "1.1.6"]]
@@ -138,7 +138,7 @@
(defn ^:private gen-react-dom-inline-fn [tag]
`(defmacro ~tag [opts# & children#]
`(~'~(symbol "js" (str "React.DOM." (name tag))) ~opts#
`(js/React.createElement ~(name tag) ~opts#
~@(clojure.core/map (fn [x#] `(om.util/force-children ~x#)) children#))))
(defmacro ^:private gen-react-dom-inline-fns []
@@ -150,9 +150,9 @@
(defn ^:private gen-react-dom-fn [tag]
`(defn ~tag [opts# & children#]
(.apply ~(symbol "js" (str "React.DOM." (name tag))) nil
(.apply ~(symbol "js" "React.createElement") nil
(cljs.core/into-array
(cons opts# (cljs.core/map om.util/force-children children#))))))
(cons ~(name tag) (cons opts# (cljs.core/map om.util/force-children children#)))))))
(defmacro ^:private gen-react-dom-fns []
`(do
@@ -8,45 +8,65 @@
(dom/gen-react-dom-fns)
(defn wrap-form-element [ctor display-name]
(js/React.createFactory
(js/React.createClass
#js
{:getDisplayName
(fn [] display-name)
:getInitialState
(fn []
(this-as this
#js {: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 {:value (.. e -target -value)})))))
:componentWillReceiveProps
(fn [new-props]
(this-as this
(.setState this #js {:value (aget new-props "value")})))
:render
(fn []
(this-as this
;; NOTE: if switch to macro we remove a closure allocation
(let [props #js {}]
(gobj/extend props (.-props this)
#js {:value (aget (.-state this) "value")
:onChange (aget this "onChange")
:children (aget (.-props this) "children")})
(ctor props))))})))
(defn- update-state
"Updates the state of the wrapped input element."
[component next-props value]
(let [on-change (gobj/getValueByKeys component "state" "onChange")
next-state #js {}]
(gobj/extend next-state next-props #js {:onChange on-change})
(gobj/set next-state "value" value)
(.setState component next-state)))
(def input (wrap-form-element js/React.DOM.input "input"))
(defn wrap-form-element [element]
(let [ctor (fn [props]
(this-as this
(set! (.-state this)
(let [state #js {}]
(->> #js {:onChange (goog/bind (gobj/get this "onChange") this)}
(gobj/extend state props))
state))
(.apply js/React.Component this (js-arguments))))]
(set! (.-displayName ctor) (str "wrapped-" element))
(goog.inherits ctor js/React.Component)
(specify! (.-prototype ctor)
Object
(onChange [this event]
(when-let [handler (.-onChange (.-props this))]
(handler event)
(update-state
this (.-props this)
(gobj/getValueByKeys event "target" "value"))))
(def textarea (wrap-form-element js/React.DOM.textarea "textarea"))
(componentWillReceiveProps [this new-props]
(let [state-value (gobj/getValueByKeys this "state" "value")
element-value (gobj/get (js/ReactDOM.findDOMNode this) "value")]
;; 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.
;; Ignoring this causes skipped letters in controlled
;; components
;; https://github.com/facebook/react/issues/7027
;; https://github.com/reagent-project/reagent/issues/253
;; https://github.com/tonsky/rum/issues/86
;; TODO: Find a better solution, since this conflicts
;; with controlled/uncontrolled inputs.
;; https://github.com/r0man/sablono/issues/148
(if (not= state-value element-value)
(update-state this new-props element-value)
(update-state this new-props (gobj/get new-props "value")))))
(def option (wrap-form-element js/React.DOM.option "option"))
(render [this]
(js/React.createElement element (.-state this))))
(js/React.createFactory ctor)))
(def select (wrap-form-element js/React.DOM.select "select"))
(def input (wrap-form-element "input"))
(def textarea (wrap-form-element "textarea"))
(def option (wrap-form-element "option"))
(def select (wrap-form-element "select"))
(defn render
"Equivalent to React.render"
@@ -187,9 +187,11 @@
:defaults
`{~'isMounted
([this#]
(boolean
(goog.object/getValueByKeys this#
"_reactInternalInstance" "_renderedComponent")))
(boolean
(or (some-> this# .-_reactInternalFiber .-tag)
;; Pre React 16 support. Remove when we don't wish to support
;; React < 16 anymore - Antonio
(some-> this# .-_reactInternalInstance .-_renderedComponent))))
~'shouldComponentUpdate
([this# next-props# next-state#]
(let [next-children# (. next-props# -children)

0 comments on commit fa67729

Please sign in to comment.