Fork me on GitHub
#reagent
<
2021-12-19
>
B Treebeard01:12:22

Hi, I get a `Can't perform a React state update on an unmounted component.` warning when using a function component. Specifically, this pops up when Shadow CLJS hot reloads upon save. Here's a minimal repro:

(def state (reagent.core/atom 0))

(defn ref-fn []
  (swap! state inc))

(defn child []
  [:span "World!"])

(defn parent []
  [:div {:ref ref-fn}
   "Hello, "
   [child @state]])

(reagent.dom/render [:f> parent]
                    (. js/document (getElementById "app")))
Is this because with `parent` unmounting, when the `div` unmounts, it causes the `ref` callback to fire and update the state, which presumably (asynchronously?) causes `child` to update, but `child` has already unmounted by then? [Update: I've managed to reproduce this outside of Shadow now.]

lilactown01:12:51

your diagnosis of the problem is correct

lilactown01:12:02

a common pattern is to check for when the value passed to your ref callback is non-nil, i.e.

(defn ref-fn [node]
  (when node
    ;; do stuff
    ))

👍 1
B Treebeard01:12:06

@lilactown Thanks for confirming. Yup, I knew about the callback with nil. I was just surprised that Reagent doesn't "unsubscribe" child from updates to the state atom when child unmounts. But I don't know enough about Reagent internals, so maybe this isn't feasible for some reason. I've put in your non-`nil` check now, but I still see the warning pop up occasionally with Shadow hot reload.

B Treebeard12:12:09

For posterity's sake - figured out this was indeed to do with Reagent's aysnc rendering, and got rid of the warning by using (flush).