Skip to content

Commit 3c1cffe

Browse files
committed
Allow subscribe to be safely called from any context
The `warn-when-not-reactive` warnings are no longer valid if we bypass the subscription cache when not in a reagent component, so they've been removed. This should address issue #753 Still needs some testing, and probably some documentation cleanup
1 parent 69cf395 commit 3c1cffe

File tree

1 file changed

+23
-29
lines changed

1 file changed

+23
-29
lines changed

src/re_frame/subs.cljc

+23-29
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,29 @@
3535
(defn cache-and-return
3636
"cache the reaction r"
3737
[query-v dynv r]
38-
(let [cache-key [query-v dynv]]
39-
;; when this reaction is no longer being used, remove it from the cache
40-
(add-on-dispose! r #(trace/with-trace {:operation (first-in-vector query-v)
41-
:op-type :sub/dispose
42-
:tags {:query-v query-v
43-
:reaction (reagent-id r)}}
44-
(swap! query->reaction
45-
(fn [query-cache]
46-
(if (and (contains? query-cache cache-key) (identical? r (get query-cache cache-key)))
47-
(dissoc query-cache cache-key)
48-
query-cache)))))
49-
;; cache this reaction, so it can be used to deduplicate other, later "=" subscriptions
50-
(swap! query->reaction (fn [query-cache]
51-
(when debug-enabled?
52-
(when (contains? query-cache cache-key)
53-
(console :warn "re-frame: Adding a new subscription to the cache while there is an existing subscription in the cache" cache-key)))
54-
(assoc query-cache cache-key r)))
55-
(trace/merge-trace! {:tags {:reaction (reagent-id r)}})
56-
r)) ;; return the actual reaction
38+
;; Only cache the reaction when subscribe is called from a reactive context
39+
;; where a reagent component will be able to purge the reaction from the subscription cache
40+
;; when the component is dismounted.
41+
(when (reactive?)
42+
(let [cache-key [query-v dynv]]
43+
;; when this reaction is no longer being used, remove it from the cache
44+
(add-on-dispose! r #(trace/with-trace {:operation (first-in-vector query-v)
45+
:op-type :sub/dispose
46+
:tags {:query-v query-v
47+
:reaction (reagent-id r)}}
48+
(swap! query->reaction
49+
(fn [query-cache]
50+
(if (and (contains? query-cache cache-key) (identical? r (get query-cache cache-key)))
51+
(dissoc query-cache cache-key)
52+
query-cache)))))
53+
;; cache this reaction, so it can be used to deduplicate other, later "=" subscriptions
54+
(swap! query->reaction (fn [query-cache]
55+
(when debug-enabled?
56+
(when (contains? query-cache cache-key)
57+
(console :warn "re-frame: Adding a new subscription to the cache while there is an existing subscription in the cache" cache-key)))
58+
(assoc query-cache cache-key r)))
59+
(trace/merge-trace! {:tags {:reaction (reagent-id r)}})))
60+
r) ;; Always return the actual reaction, even if it was not cached.
5761

5862
(defn cache-lookup
5963
([query-v]
@@ -63,17 +67,8 @@
6367

6468
;; -- subscribe ---------------------------------------------------------------
6569

66-
(defn warn-when-not-reactive
67-
[]
68-
(when (and debug-enabled? (not (reactive?)))
69-
(console :warn
70-
"re-frame: Subscribe was called outside of a reactive context.\n"
71-
"See: https://day8.github.io/re-frame/FAQs/UseASubscriptionInAJsEvent/\n"
72-
"https://day8.github.io/re-frame/FAQs/UseASubscriptionInAnEventHandler/")))
73-
7470
(defn subscribe
7571
([query]
76-
(warn-when-not-reactive)
7772
(trace/with-trace {:operation (first-in-vector query)
7873
:op-type :sub/create
7974
:tags {:query-v query}}
@@ -92,7 +87,6 @@
9287
(cache-and-return query [] (handler-fn app-db query)))))))
9388

9489
([query dynv]
95-
(warn-when-not-reactive)
9690
(trace/with-trace {:operation (first-in-vector query)
9791
:op-type :sub/create
9892
:tags {:query-v query

0 commit comments

Comments
 (0)