Fork me on GitHub
#reagent
<
2019-10-01
>
Pontus11:10:41

Hi, I'm trying to use react 16 error boundaries in Reagent 8.1 (React version 16.3.2). Could anyone explain why it seems they can only be used with components and not wrap hiccup directly? So for instance, this works:

(defn will-fail []
 [:div {:class js/nonExistingVar}])

(defn component []
 [error-boundary
  [will-fail]]) ; Uncaught ReferenceError: nonExistingVar is not defined (get's caught by the error boundary.)
but inlining the same component as hiccup doesn't work (it unmounts the whole component tree):
(defn component []
 [error-boundary
  [:div {:class js/nonExistingVar}]))
The error boundary looks like this:
(ns vd.frontend.shared.error-boundary
  (:require [reagent.core :as reagent]))

(defn component [_]
  (let [error? (reagent/atom false)]
    (reagent/create-class
      {:component-did-catch (fn [_ error info]
                              (js/console.log :error error)
                              (js/console.log :info info)

                              (reset! error? true))

       :reagent-render
       (fn [& comp]
         (if @error?
           [:div "something went wrong"]
           [:div.error-boundary
            comp]))})))

lilactown13:10:34

@pontus.colliander this is because Reagent/React create elements lazily

lilactown13:10:05

in the first case, the error-boundary is instantiated and passed the hiccup with will-fail

lilactown13:10:12

will-fail is then instantiated and errors

lilactown13:10:19

error-boundary then catches the error

lilactown13:10:00

in the second case, [:div {:class js/nonExistingVar}] is executed and throws an error, before error-boundary is instantiated

lilactown14:10:54

this is expected behavior

lilactown14:10:10

here’s a codepen that shows how this works in regular react: https://codepen.io/lilactown/pen/dybBrpJ?editors=0011

Pontus14:10:46

Ah I see, thanks for the explanation and the codepen example 🙂

isak16:10:41

For reagent.ratom/make-reaction, there is an :on-dispose option. Anyone know how this is supposed to be used? My reaction is getting "disposed" when I blur a field, but then the same reaction is still getting reused later (when I focus the field). And I don't see something like the opposite of :on-dispose to be able to handle that properly.

isak16:10:50

(The reaction is being returned from a "reg-sub-raw" in re-frame)

lilactown16:10:52

disposal happens when the “watch count” goes from a positive number to 0

lilactown16:10:44

e.g. if you have a component that optionally dereferences a the reaction depending on some other value:

(defn thing [count]
  ;; if this component is the only one dereferencing `message`,
  ;; this will dispose the `message` reaction when `count` > 5
  [:div (if (> count 5) "Too big!" @message)])

isak16:10:59

Makes sense. Is there something like an add_watch-watch?

isak16:10:15

I.e., If I do a side-effect in :on-dispose, is there a way to do the opposite side-effect later? (when watch-count is > 0)

lilactown16:10:13

The idea of on-dispose is that it should do some cleanup of whatever happened when the reaction was instantiated

lilactown16:10:03

E.g. the reaction is subscribing to some event stream, and on disposal it unsubscribs

isak16:10:24

Yea that makes sense, though it becomes problematic if the same reaction instance can still be reused again later, and there is no way to react to it "waking up" again

lilactown16:10:48

You shouldn't cache the reaction instance itself. I'm not clear how re-frame works exactly here, but if you dereference it again it should run the reaction again if it was disposed

isak16:10:48

Hmm ok, I'll post an issue on re-frame

Alexis Vincent18:10:53

is there any way to track reactions outside of the reagent render context?

lilactown20:10:33

interesting. I guess there’s some downsides to the caching that re-frame does in subscribe

lilactown20:10:03

I guess people rarely hit it because passing around the reaction itself isn’t super common

lilactown20:10:25

as well as, I think reg-sub-raw isn’t used very often

isak20:10:30

yeah, and even if you do, relying on proper dispose is even less common

lilactown20:10:41

yep yep. most people aren’t doing complex things with on-dispose

lilactown20:10:45

glad you figured it out

🙂 4