From 88fa3cc4ab904f99adfdccb5dc4bdae958d78e3f Mon Sep 17 00:00:00 2001 From: Juho Teperi Date: Wed, 2 Oct 2019 15:37:21 +0300 Subject: [PATCH] Improve error boundary docs and fix tests --- doc/ReactFeatures.md | 19 ++++++++++++------- package-lock.json | 23 +++++++++++------------ test/reagenttest/testreagent.cljs | 9 ++++----- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/doc/ReactFeatures.md b/doc/ReactFeatures.md index 8af5001..f55390a 100644 --- a/doc/ReactFeatures.md +++ b/doc/ReactFeatures.md @@ -51,15 +51,16 @@ Tests contain example of using old React lifecycle Context API (`context-wrapper [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`: +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 {}) + {:component-did-catch (fn [this e info]) + :get-derived-state-from-error-test (fn [e] + (reset! error e) + #js {}) :reagent-render (fn [comp] (if @error [:div @@ -76,8 +77,7 @@ can be more obvious with the new `getDerivedStateFromError` method: (r/create-class {: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)) + :component-did-catch (fn [this e info]) :get-derived-state-from-error-test (fn [error] #js {:error error}) :render (fn [this] (r/as-element @@ -85,9 +85,14 @@ can be more obvious with the new `getDerivedStateFromError` method: [:div "Something went wrong." [:button {:on-click #(.setState this #js {:error nil})} "Try again"]] - comp))}))) + (into [:<>] (r/children this)))}))) ``` +As per React docs, `getDerivedStateFromError` is what should update the state +after error, it can be also used to update RAtom as in Reagent the Ratom is available +in function closure even for static methods. `ComponentDidCatch` can be used +for side-effects, like logging the error. + ## [Hooks](https://reactjs.org/docs/hooks-intro.html) Hooks can't be used inside class components, and Reagent implementation creates diff --git a/package-lock.json b/package-lock.json index b107cca..8c6ca2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2863,25 +2863,24 @@ } }, "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", + "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "prop-types": "^15.6.2" } }, "react-dom": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", - "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz", + "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.13.6" + "scheduler": "^0.15.0" } }, "read-pkg": { @@ -3035,9 +3034,9 @@ "dev": true }, "scheduler": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", - "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", + "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" diff --git a/test/reagenttest/testreagent.cljs b/test/reagenttest/testreagent.cljs index 1c1103d..3ca8203 100644 --- a/test/reagenttest/testreagent.cljs +++ b/test/reagenttest/testreagent.cljs @@ -1042,16 +1042,16 @@ (let [error (r/atom nil) error-boundary (fn error-boundary [comp] (r/create-class - {:component-did-catch (fn [this e info] - (reset! error e)) - :get-derived-state-from-error (fn [error] + {:component-did-catch (fn [this e info]) + :get-derived-state-from-error (fn [e] + (reset! error e) #js {}) :reagent-render (fn [comp] (if @error [:div "Something went wrong."] comp))})) comp1 (fn comp1 [] - (throw (js/Error. "Test error")))] + (throw (js/Error. "Test error")))] (debug/track-warnings (wrap-capture-window-error (wrap-capture-console-error @@ -1304,7 +1304,6 @@ #js {:hasError true}) :component-did-catch (fn [this e info]) :render (fn [this] - (js/console.log (r/children this)) (r/as-element (if (.-hasError (.-state this)) [:p "Error"] (into [:<>] (r/children this)))))})