Load ReactDOM and ReactDOMServer lazily

This commit is contained in:
Dan Holmsand 2015-10-15 13:56:05 +02:00
parent f280e979c8
commit 7cbde6f115
3 changed files with 47 additions and 25 deletions

View File

@ -80,8 +80,8 @@ Returns the mounted component instance."
(defn render-to-string (defn render-to-string
"Turns a component into an HTML string." "Turns a component into an HTML string."
([component] [component]
(server/render-to-string component))) (server/render-to-string component))
;; For backward compatibility ;; For backward compatibility
(def as-component as-element) (def as-component as-element)
@ -90,8 +90,8 @@ Returns the mounted component instance."
(defn render-to-static-markup (defn render-to-static-markup
"Turns a component into an HTML string, without data-react-id attributes, etc." "Turns a component into an HTML string, without data-react-id attributes, etc."
([component] [component]
(server/render-to-static-markup component))) (server/render-to-static-markup component))
(defn ^:export force-update-all (defn ^:export force-update-all
"Force re-rendering of all mounted Reagent components. This is "Force re-rendering of all mounted Reagent components. This is

View File

@ -5,21 +5,29 @@
[reagent.debug :refer-macros [dbg]] [reagent.debug :refer-macros [dbg]]
[reagent.interop :refer-macros [.' .!]])) [reagent.interop :refer-macros [.' .!]]))
(defonce react-dom (or (and (exists? js/ReactDOM) (defonce ^:private react-dom nil)
js/ReactDOM)
(and (exists? js/require)
(js/require "react-dom"))))
(assert react-dom)
(defonce ^:private roots (atom {})) (defonce ^:private roots (atom {}))
(defn unmount-comp [container] (defn- dom []
(if-some [r react-dom]
r
(do
(set! react-dom
(or (and (exists? js/ReactDOM)
js/ReactDOM)
(and (exists? js/require)
(js/require "react-dom"))))
(assert react-dom "Could not find ReactDOM")
react-dom)))
(defn- unmount-comp [container]
(swap! roots dissoc container) (swap! roots dissoc container)
(.' react-dom unmountComponentAtNode container)) (.' (dom) unmountComponentAtNode container))
(defn- render-comp [comp container callback] (defn- render-comp [comp container callback]
(binding [util/*always-update* true] (binding [util/*always-update* true]
(->> (.' react-dom render (comp) container (->> (.' (dom) render (comp) container
(fn [] (fn []
(binding [util/*always-update* false] (binding [util/*always-update* false]
(swap! roots assoc container [comp container]) (swap! roots assoc container [comp container])
@ -49,11 +57,21 @@ Returns the mounted component instance."
(defn dom-node (defn dom-node
"Returns the root DOM node of a mounted component." "Returns the root DOM node of a mounted component."
[this] [this]
(.' react-dom findDOMNode this)) (.' (dom) findDOMNode this))
(set! tmpl/find-dom-node dom-node) (set! tmpl/find-dom-node dom-node)
(defn force-update-all [] (defn force-update-all
"Force re-rendering of all mounted Reagent components. This is
probably only useful in a development environment, when you want to
update components in response to some dynamic changes to code.
Note that force-update-all may not update root components. This
happens if a component 'foo' is mounted with `(render [foo])` (since
functions are passed by value, and not by reference, in
ClojureScript). To get around this you'll have to introduce a layer
of indirection, for example by using `(render [#'foo])` instead."
[]
(doseq [v (vals @roots)] (doseq [v (vals @roots)]
(apply re-render-component v)) (apply re-render-component v))
"Updated") "Updated")

View File

@ -4,20 +4,24 @@
[reagent.impl.template :as tmpl] [reagent.impl.template :as tmpl]
[reagent.interop :refer-macros [.' .!]])) [reagent.interop :refer-macros [.' .!]]))
;; TODO: Where the hell is ReactDOMServer? (defonce ^:private react-server nil)
(defonce react-dom-server (or (and (exists? js/require)
(js/require "react-dom/server")) (defn- server []
util/react)) (if-some [r react-server]
(assert react-dom-server) r
(set! react-server
(or (and (exists? js/require)
(js/require "react-dom/server"))
util/react))))
(defn render-to-string (defn render-to-string
"Turns a component into an HTML string." "Turns a component into an HTML string."
([component] [component]
(binding [util/*non-reactive* true] (binding [util/*non-reactive* true]
(.' react-dom-server renderToString (tmpl/as-element component))))) (.' (server) renderToString (tmpl/as-element component))))
(defn render-to-static-markup (defn render-to-static-markup
"Turns a component into an HTML string, without data-react-id attributes, etc." "Turns a component into an HTML string, without data-react-id attributes, etc."
([component] [component]
(binding [util/*non-reactive* true] (binding [util/*non-reactive* true]
(.' react-dom-server renderToStaticMarkup (tmpl/as-element component))))) (.' (server) renderToStaticMarkup (tmpl/as-element component))))