Skip to content

Commit ea07fb5

Browse files
committed
Use async cleanup for fn components to avoid double cleanup on StrictMode
1 parent d7d5e78 commit ea07fb5

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

src/reagent/impl/component.cljs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,11 +427,24 @@
427427
;; FIXME: Access cljsRatom using interop forms
428428
rat ^ratom/Reaction (gobj/get reagent-state "cljsRatom")]
429429

430+
;; Run ratom dispose async with zero-delay,
431+
;; this is used to cancel the extra cleanup on the second setup fn call,
432+
;; so we can ensure dispose is only called when the component is really unmounted.
430433
(react/useEffect
431434
(fn mount []
435+
(when-let [t (.-cleanup-callback reagent-state)]
436+
(js/clearTimeout t)
437+
(set! (.-cleanup-callback reagent-state) nil))
432438
(fn unmount []
433-
(some-> (gobj/get reagent-state "cljsRatom") ratom/dispose!)))
439+
(set! (.-cleanup-callback reagent-state)
440+
(js/setTimeout (fn []
441+
(some-> (gobj/get reagent-state "cljsRatom") ratom/dispose!)
442+
(set! (.-cleanup-callback reagent-state) nil))
443+
;; Is zero delay enough to get these to run async in strict mode? Seems like it. StrictMode likely calls
444+
;; these synchronously so any async operation is enough to get this delayed.
445+
0))))
434446
;; Ignore props - only run effect once on mount and unmount
447+
;; (which means always twice under the React strict mode).
435448
#js [])
436449

437450
;; Argv is also stored in the state,

0 commit comments

Comments
 (0)