Last active
May 13, 2017 11:48
-
-
Save pesterhazy/60ec2b43709bbc8d8a7c324077466df1 to your computer and use it in GitHub Desktop.
Testing pesterhazy/recalcitrant error-boundary for reagent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;loaded from gist: https://gist.github.com/pesterhazy/60ec2b43709bbc8d8a7c324077466df1 | |
(ns my.test | |
(:require [reagent.core :as r] | |
[reagent.impl.component :as comp] | |
[reagent.impl.util :as util] | |
[reagent.debug :refer-macros [dev?]] | |
[goog.object :as gobj])) | |
(enable-console-print!) | |
(def error-boundary | |
"Wrapper component for recovering from exceptions in downstream | |
render fns. Creates an error boundary that prevents exceptions from corrupting | |
the React component hierarchy. | |
Use this component to wrap a single reagent (root) component. Any exception | |
thrown in downstream render fns will be caught and logged. The component's | |
child and its children will not be rendered. | |
This is useful in a reloading-based development workflow. | |
Example usage: | |
(ns my-ns | |
(:require [error-boundary.error-boundary :refer [error-boundary]])) | |
(r/render-component (fn [] [error-boundary [root]]) | |
(.. js/document (querySelector \"#container\"))) | |
Note that this relies on the undocumented unstable_handleError API introduced | |
in React 15. | |
This componenet may have performance implications, so it is recommended to | |
enable it only during development." | |
(if (dev?) | |
(r/adapt-react-class (comp/create-class | |
{:getInitialState | |
(fn [] | |
#js {:error false}) | |
:unstable_handleError | |
(fn [e] | |
(this-as this | |
(if (ex-data e) | |
(js/console.error (pr-str e)) | |
(js/console.error e)) | |
(.setState this #js {:error true}))) | |
:render | |
(fn [] | |
(this-as this | |
(let [children ((-> util/react | |
(gobj/get "Children") | |
(gobj/get "toArray")) | |
(-> this | |
(gobj/get "props") | |
(gobj/get "children")))] | |
(when (not= 1 (count children)) | |
(js/console.warn "Component error-boundary requires a single child component. Additional children are ignored.")) | |
(if (-> this | |
(gobj/get "state") | |
(gobj/get "error")) | |
(do | |
(js/console.warn "An error occurred downstream (see errors above). The element subtree will not be rendered.") | |
nil) | |
(first children)))))})) | |
(r/adapt-react-class (comp/create-class | |
{:render | |
(fn [] | |
(this-as this | |
(let [children ((-> util/react | |
(gobj/get "Children") | |
(gobj/get "toArray")) | |
(-> this | |
(gobj/get "props") | |
(gobj/get "children")))] | |
(first children))))})))) | |
(defn explode [] | |
;; remove comment to cause an exception. | |
;; add comment back in to see component recover | |
#_(throw "kaboom") | |
[:div "All good"]) | |
(defn root [] | |
[:div | |
[:h1 "Error boundary test"] | |
[explode]]) | |
(r/render (fn [] [error-boundary [root]]) js/klipse-container) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See live demo here: http://app.klipse.tech/?cljs_in.gist=pesterhazy/60ec2b43709bbc8d8a7c324077466df1&container=1