This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-08
Channels
- # beginners (36)
- # calva (13)
- # cider (3)
- # clerk (7)
- # clj-http (2)
- # clj-kondo (10)
- # clojure (20)
- # clojure-europe (14)
- # clojure-nl (1)
- # clojure-norway (26)
- # clojure-uk (5)
- # clojurescript (143)
- # dev-tooling (7)
- # events (1)
- # exercism (1)
- # honeysql (8)
- # hyperfiddle (4)
- # jobs-discuss (15)
- # leiningen (3)
- # lsp (31)
- # off-topic (17)
- # overtone (3)
- # pathom (11)
- # pedestal (11)
- # re-frame (15)
- # reitit (17)
- # releases (1)
- # scittle (2)
- # shadow-cljs (29)
- # squint (1)
- # yamlscript (3)
I am having an issue where child component doesn't render data from a subscription in parent component on refresh. Below is a simplified version of my code:
(defn parent-component []
(let [data @(rf/subscribe [:my-sub])
on-change (fn [e] (js/alert e))]
[child-component data on-change]))
(defn child-component [items on-change]
(let [transformed-items (map #(assoc {} :value (:code %) :label (:name %)) items)]
;; Rendering logic using transformed-items
))
(rf/reg-sub
:my-sub
(fn [db _]
(:items db)))
So, the data is shown on initial render, but not when I refresh the page.
For now, as a work around, I'm passing subscription key into the child component and
subscribing to it inside the child component. I don't like that approach
because it assumes the data will always come from a re-frame subscription,
thereby making compromising component reusability.
Also, please let me know if this work around is sort of an "anti-pattern"
besides making the component less reusable. Thanks.
What does that "Rendering logic using transformed-items" look like? What do you mean by "initial render"? How is it different from a page refresh?
When the shadow-cljs live reloading happens, I can see the data, but not when I refresh the browser. The rendering logic is antD combo bound to the items, but I've noticed that doesn't make much of difference because when I pass in static data, it works just fine. You can even think of it like regular HTML dropdown
Hard to say anything without the actual code.
Maybe child-component
is a form-2 or form-3 component that gets fully re-rendered on hot reload but doesn't get re-rendered on plain data change.
Maybe you have a hot reload hook that does something weird.
Maybe it's a global interceptor problem. Maybe some global def is causing issues. And so on and on.
Here's the child component followed by the usage:
(defn selector [items on-change label]
(let [transformed-items (map #(into {}
(map (fn [[k v]] {(case k
:code :value
:name :label
:id :id
:type :type)
v}) %))
items)]
(fn []
[:div.column
;; align left
[:div.field
[:div.label.is-normal {:style {:white-space "nowrap"}}
[:label.label label]]
[:div.field-body
[:div.field
[:div.control.is-fullwidth
[:> Select
(assoc
{:style {:width "100%" :height 40}
:onChange on-change
:options transformed-items
:optionFilterProp "label"} ;; TODO: Check if there's a generic version
:k "v")]]]]]])))
(defn my-selector []
(let [on-change (fn [e] (js/alert e))
data @(rf/subscribe [:sub-key])]
[selector data on-change ""]
))
Turn it from a form-2 component into a form-1 component. With that code, there's 0 reason to keep it as form-2.
Can you try with form-1 again? How does the code that doesn't work with form-1 look like?
(let [transformed-items (map #(into {}
(map (fn [[k v]] {(case k ;; Meh ... no need to transform all keys FIXME
:code :value :name :label :id :id :type :type) v}) %))
items)]
(fn []
[:div.column
[:div.field
[:div.label.is-normal {:style {:white-space "nowrap"}}
[:label.label label]]
[:div.field-body
[:div.field
[:div.control.is-fullwidth
[:> Select
(assoc
{:style {:width "100%" :height 40}
:onChange on-change
:options transformed-items
:optionFilterProp "label"} ;; TODO: Check if there's a generic version
:k "v")]]]]]])))
I have no clue what that code is, but it's definitely not a form-1 component. Also, please use code blocks to format multiline code.
My bad. It wasn't supposed to be wrapped inside a function. It works now that I removed the function. I guess that's a form-1. Didn't know about code block. Thanks.
Because of the "Rookie mistake" sub-section in this section: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md#form-2--a-function-returning-a-function