This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-19
Channels
- # adventofcode (36)
- # asami (3)
- # babashka (22)
- # beginners (65)
- # calva (5)
- # clj-kondo (1)
- # cljs-dev (3)
- # clojure-europe (1)
- # clojurescript (3)
- # conjure (1)
- # core-async (6)
- # datomic (3)
- # emacs (4)
- # introduce-yourself (3)
- # juxt (11)
- # lsp (64)
- # malli (10)
- # missionary (11)
- # music (1)
- # off-topic (2)
- # pathom (1)
- # practicalli (1)
- # reagent (6)
- # reitit (3)
- # releases (3)
- # xtdb (9)
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.]@b.treebeard React calls your ref callback with nil
when it unmounts https://reactjs.org/docs/refs-and-the-dom.html#callback-refs
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
))
@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.
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)
.