Delay error reporting of missing ReactDOM[Server]

This should improve error messages, and allow Reagent to be used
without ReactDOM[Server] being present at all.
This commit is contained in:
Dan Holmsand 2016-02-24 13:27:43 +01:00
parent ef21172591
commit f76bce6a2f
3 changed files with 45 additions and 16 deletions

View File

@ -1,4 +1,4 @@
(defproject reagent "0.6.0-alpha" (defproject reagent "0.6.0-SNAPSHOT"
:url "http://github.com/reagent-project/reagent" :url "http://github.com/reagent-project/reagent"
:license {:name "MIT"} :license {:name "MIT"}
:description "A simple ClojureScript interface to React" :description "A simple ClojureScript interface to React"

View File

@ -5,22 +5,36 @@
[reagent.debug :refer-macros [dbg]] [reagent.debug :refer-macros [dbg]]
[reagent.interop :refer-macros [$ $!]])) [reagent.interop :refer-macros [$ $!]]))
(defonce dom (or (and (exists? js/ReactDOM) (def ^:private load-error nil)
js/ReactDOM)
(and (exists? js/require)
(js/require "react-dom"))))
(assert dom "Could not find ReactDOM") (defn- fail [e]
(set! load-error e)
nil)
(defonce dom (or (when (exists? js/ReactDOM)
js/ReactDOM)
(try
(if (exists? js/require)
(or (js/require "react-dom")
(fail (js/Error. "require('react-dom') failed")))
(fail (js/Error. "js/ReactDOM is missing")))
(catch :default e
(fail e)))))
(defn- module []
(if (some? dom)
dom
(throw load-error)))
(defonce ^:private roots (atom {})) (defonce ^:private roots (atom {}))
(defn- unmount-comp [container] (defn- unmount-comp [container]
(swap! roots dissoc container) (swap! roots dissoc container)
($ dom unmountComponentAtNode container)) ($ (module) unmountComponentAtNode container))
(defn- render-comp [comp container callback] (defn- render-comp [comp container callback]
(binding [util/*always-update* true] (binding [util/*always-update* true]
(->> ($ dom render (comp) container (->> ($ (module) 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])
@ -50,7 +64,7 @@
(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]
($ dom findDOMNode this)) ($ (module) findDOMNode this))
(set! tmpl/find-dom-node dom-node) (set! tmpl/find-dom-node dom-node)

View File

@ -4,21 +4,36 @@
[reagent.impl.template :as tmpl] [reagent.impl.template :as tmpl]
[reagent.interop :refer-macros [$ $!]])) [reagent.interop :refer-macros [$ $!]]))
(defonce server (or (and (exists? js/ReactDOMServer) (def ^:private load-error nil)
js/ReactDOMServer)
(and (exists? js/require)
(js/require "react-dom/server"))))
(assert server "Could not find ReactDOMServer") (defn- fail [e]
(set! load-error e)
nil)
(defonce server (or (when (exists? js/ReactDOMServer)
js/ReactDOMServer)
(try
(if (exists? js/require)
(or (js/require "react-dom/server")
(fail (js/Error.
"require('react-dom/server') failed")))
(fail (js/Error. "js/ReactDOMServer is missing")))
(catch :default e
(fail e)))))
(defn- module []
(if (some? server)
server
(throw load-error)))
(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]
($ server renderToString (tmpl/as-element component)))) ($ (module) 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]
($ server renderToStaticMarkup (tmpl/as-element component)))) ($ (module) renderToStaticMarkup (tmpl/as-element component))))