I want to wrap a reagent vector that includes a re-com checkbox, where the checkbox does not directly rely on a subscription, but a value that is calculated (in the component) from that subscription. I’ve boiled the problem down to the following code.
(rf/reg-sub
::get-value
(fn [db _]
(::value db)))
(rf/reg-event-fx
::set-value
(fn [{:keys [db]} [_ value]]
{:db (assoc db ::value value)}))
(defn wrapper
[body]
(fn [body] ;; adding `body`here fixed the problem. Thanks @p-himik
[:div body]))
(defn test
[]
(let [sub (rf/subscribe [::get-value])]
(fn []
[:div
[wrapper
(let [selected? @sub]
[rc/checkbox
:model selected?
:on-change #(rf/dispatch [::set-value %])
:label "Wrapped - :model is computed - doesn't work"])]
[wrapper
[rc/checkbox
:model sub
:on-change #(rf/dispatch [::set-value %])
:label "Wrapped - :model is subscription - works"]]
(let [selected? @sub]
[rc/checkbox
:model selected?
:on-change #(rf/dispatch [::set-value %])
:label "Not wrapped - :model is computed - works"])])))
I render [test]
and when I click the first checkbox, the value changes but the checkbox does not change state. So for some reason reagent doesn’t re-render it.
The two other checkboxes demonstrate that it is the combination of wrapping the checkbox and setting the :model
for the checkbox to a computed value instead of sub
that causes the problem. The reason why I am computing the value instead of using sub
directly is that I am in reality rendering lots of dynamically created checkboxes (within the same wrapper
) and I don’t want to create a subscription for each one of them, instead they dereference the subscription and check if their specific key is true
or false
.
Any idea on how I can get this to work?