A minimalistic ClojureScript interface to React.js

Well, when I try to run it in a browser context, a basic test I ran apparently gets confused with the generated result page, so I was mostly thinking about using it with jsdom. I'll give karma a shot first, though and see if that just works.


Thanks everybody for the input.

Mark Wardle 2020-05-12T10:06:45.434100Z

Ah I see. Thank you. I assumed the reagent macro did all of the js getElementById and render for an arbitrary component. So essentially I have to create a reagent “form 3” type and run getElementById and render from there into the DOM fragment? Thanks I’ll give this a try.


And of course it turns out that not react-testing-library was confused but my test and it works as a browser-test just fine.


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


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


this is a form-1 component according to reagent documentation


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

lilactown 2020-05-12T14:43:24.438Z

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

lilactown 2020-05-12T14:43:52.438600Z

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

lilactown 2020-05-12T14:44:22.439300Z


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

lilactown 2020-05-12T14:44:40.439800Z

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

lilactown 2020-05-12T14:45:23.440900Z

(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


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


and only make the dereference in the inner fn?


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

lilactown 2020-05-12T14:48:21.443100Z

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

lilactown 2020-05-12T14:48:29.443300Z

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

lilactown 2020-05-12T14:48:40.443600Z

it will only create the subscription once

lilactown 2020-05-12T14:48:47.444Z

so you may use it in a form-1


so is a matter of taste?

v 2020-05-12T14:49:12.444900Z

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

lilactown 2020-05-12T14:49:22.445300Z

yes it's a matter of taste

v 2020-05-12T14:49:24.445400Z

other than that its preferred to use form 1

v 2020-05-12T14:49:34.445800Z

form 1 makes component simpler

v 2020-05-12T14:49:51.446500Z

since it only does one thing, renders component




thanks a lot!

v 2020-05-12T14:50:44.447500Z

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

v 2020-05-12T14:50:46.447700Z

you can do that

v 2020-05-12T14:50:48.447900Z

there is a trick


I’m all ears….

v 2020-05-12T14:52:27.448600Z

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

v 2020-05-12T14:52:46.449100Z

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

v 2020-05-12T14:53:00.449400Z

and voila, no more form-2


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


thanks @lilactown and @vishal.gautam

Sean Poulter 2020-05-12T18:06:41.452800Z

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