Fork me on GitHub
#reagent
<
2020-05-12
>
Wilson Velez14:05:30

reading the channel makes me question about how I use reagent and re-frame.. this is a typical view function from my app

Wilson Velez14:05:33

(defn main-panel []
  (let [fund-filters-loaded? @(rf/subscribe [:fund.filters.subs/loaded])
        logged-profile @(rf/subscribe [:logged-profile])]
    [:<>
     [chart]
     (if fund-filters-loaded?
       [:<>
        [filters {:suspended-enabled? false
                  :custom-filter #(custom-filter logged-profile)}]
        [fund-list callback]]
       [:div "loading..."])]))

Wilson Velez14:05:03

this is a form-1 component according to reagent documentation

Wilson Velez14:05:21

my question is, should it be form-2 and return a function instead?

lilactown14:05:24

@wvelezva what you wrote works. re-frame caches subscriptions, so when your component re-renders it will get the same subscription value every time

lilactown14:05:52

the reason you'd use a form-2 is it if you wanted something to only run on component mount (first render)

lilactown14:05:22

e.g.:

(defn my-component []
  (let [count (r/atom 0)]
    [:button {:on-click #(swap! count inc)} @count]))

lilactown14:05:40

☝️ that would re-create the count atom every render, so it would always say "0"

lilactown14:05:23

(defn my-component []
  (let [count (r/atom 0)]
    (fn []
      [:button {:on-click #(swap! count inc)} @count])))
☝️ that will create the count atom on first render, and then only run the inner function each subsequent one

Wilson Velez14:05:36

I understand, and that is not desirable so in my case with the subscriptions?

Wilson Velez14:05:53

and only make the dereference in the inner fn?

Wilson Velez14:05:54

(defn main-panel []
  (let [fund-filters-loaded? (rf/subscribe [:fund.filters.subs/loaded])
        logged-profile (rf/subscribe [:logged-profile])]
    (fn []
      [:<>
       [chart]
       (if @fund-filters-loaded?
         [:<>
          [filters {:suspended-enabled? false
                    :custom-filter #(custom-filter @logged-profile)}]
          [fund-list callback]]
         [:div "loading..."])])))

lilactown14:05:21

like I said above, you can use either a form-1 or form-2 because re-frame caches subscriptions

lilactown14:05:29

(rf/subscribe [:fund.filters.subs/loaded]) will return the same thing every time

lilactown14:05:40

it will only create the subscription once

lilactown14:05:47

so you may use it in a form-1

Wilson Velez14:05:10

so is a matter of taste?

Vishal Gautam14:05:12

use form-2 if and only if, you are dealing with local states i.e using reagent to manage form state

lilactown14:05:22

yes it's a matter of taste

Vishal Gautam14:05:24

other than that its preferred to use form 1

Vishal Gautam14:05:34

form 1 makes component simpler

Vishal Gautam14:05:51

since it only does one thing, renders component

Vishal Gautam14:05:44

how ever, if you still want to use form 1 component while managing local state

Vishal Gautam14:05:46

you can do that

Vishal Gautam14:05:48

there is a trick

Wilson Velez14:05:15

I’m all ears….

Vishal Gautam14:05:27

(defn simple-form [args]
  (reagent/with-let
   [state (reagent/atom {:username ""})]
   [:form
    [:input {:type :text
             :placeholder :username
             :on-change #(swap! state assoc :username (-> % .-target .-value))
             :value (:username @state)}]]))

Vishal Gautam14:05:46

the trick is to wrap the component with with-let function

Vishal Gautam14:05:00

and voila, no more form-2

Wilson Velez14:05:27

the code I inherited had those with-let plus the subscriptions, when I started learning I didn’t see any difference between with-let and the “simple” let so I adopted that style

Sean Poulter18:05:41

Anyone know if it is possible to configure the React Dev Tools to highlight updates to Reagent components? 🤞