From edb3d2d322b46abda06d20e4fce2de7daa92e98e Mon Sep 17 00:00:00 2001 From: Juho Teperi Date: Wed, 2 Oct 2019 12:59:00 +0300 Subject: [PATCH] Document using getDerivedStateFromError with error boundaries --- doc/ReactFeatures.md | 42 ++++++++++++++++++++++++------- test/reagenttest/testreagent.cljs | 2 ++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/doc/ReactFeatures.md b/doc/ReactFeatures.md index 552cbe6..8af5001 100644 --- a/doc/ReactFeatures.md +++ b/doc/ReactFeatures.md @@ -49,19 +49,43 @@ Tests contain example of using old React lifecycle Context API (`context-wrapper ## [Error boundaries](https://reactjs.org/docs/error-boundaries.html) -You can use `ComponentDidCatch` lifecycle method with `create-class`: +[Relevant method docs](https://reactjs.org/docs/react-component.html#static-getderivedstatefromerror) + +You can use `getDerivedStateFromError` (since React 16.6.0 and Reagent 0.9) and `ComponentDidCatch` lifecycle method with `create-class`: + +```cljs +(defn error-boundary [comp] + (let [error (r/atom nil)] + (r/create-class + {:component-did-catch (fn [this e info] + (reset! error e)) + :get-derived-state-from-error-test (fn [error] #js {}) + :reagent-render (fn [comp] + (if @error + [:div + "Something went wrong." + [:button {:on-click #(reset! error nil)} "Try again"]] + comp))}))) +``` + +Alternatively, one could use React state instead of RAtom to keep track of error state, which +can be more obvious with the new `getDerivedStateFromError` method: ```cljs (defn error-boundary [comp] (r/create-class - {:component-did-catch (fn [this e info] - (reset! error e)) - :reagent-render (fn [comp] - (if @error - [:div - "Something went wrong." - [:button {:on-click #(reset! error nil)} "Try again"]] - comp))})) + {:constructor (fn [this props] + (set! (.-state this) #js {:error nil})) + :component-did-catch (fn [this e info] + (js/console.error "Error inside error boundary" e)) + :get-derived-state-from-error-test (fn [error] #js {:error error}) + :render (fn [this] + (r/as-element + (if @error + [:div + "Something went wrong." + [:button {:on-click #(.setState this #js {:error nil})} "Try again"]] + comp))}))) ``` ## [Hooks](https://reactjs.org/docs/hooks-intro.html) diff --git a/test/reagenttest/testreagent.cljs b/test/reagenttest/testreagent.cljs index 904aaf1..1c1103d 100644 --- a/test/reagenttest/testreagent.cljs +++ b/test/reagenttest/testreagent.cljs @@ -1044,6 +1044,8 @@ (r/create-class {:component-did-catch (fn [this e info] (reset! error e)) + :get-derived-state-from-error (fn [error] + #js {}) :reagent-render (fn [comp] (if @error [:div "Something went wrong."]