Fork me on GitHub

I have a background image element which is not required on mobile. It is quite heavy and does some image preloading when it mounts using images with :on-load functions. I was surprised to find that (when (not @mobile) [bg-element @images]) actually was triggering the preloading events, even when @mobile is false


Is there a way to make the sub-component render only when @mobile is true?


oh wow.. I must be doing something wrong this only logs component1 as I'd expect..


I wasn't initializing the @mobile atom at the right time so it was defaulting to false 🤕


@pishty if you look at the Installation section of cljs-react-material-ui:, they mention that you need to exclude some packages to get onTouchTap event working


I recently heard here that Reagent doesn’t do well with multimethods. What is the reasoning behind this?


that's it. I haven't seen a bug report for this, but multiple reports of components failing to update because they're implemented as multimethods


hi, I get this error while trying to build with lein do clean, uberjar : Could not locate prone/middleware__init.class or prone/middleware.clj on classpath., compiling:(middleware.clj:1:1)


I have some middleware functions I use in /env/prod/clj/middleware.clj as well as /env/dev/clj/middleware.clj


@tomaas could you post some source code related to the namespace prone.middleware or the relevant contents of /env/prod/clj/middleware.clj?


@pesterhazy a few days ago you linked me to your blog post about the :ref property. i just noticed an odd behaviour... maybe you know what's going on? in this example the function value of the :ref key on the [:input] element never gets called. (i added a :ref key to the outer div just to make sure that works, and i do get ref1 in the console, but not ref2):

(defn constraint-text-input []
  (let [component (reagent/atom nil)]
    (fn [& {:keys [value on-change on-blur allow-possible-values possible-values]}]
       {:ref (fn [el] (println "ref1" el))}
        {:data-toggle "dropdown"
         :ref         (fn [el] (println "ref2" el))
         :type        "text"
         :on-change   (fn [e] (on-change (oget e :target :value)))
         :on-blur     (fn [x] (on-blur))
         :value       value}]])))


@joshk, I have a suspicion


first of all usually refs to inputs should work


reagent does some special handling for input elements, however


are you on reagent 0.6.0? there may be a recently fixed bug in earlier versions


looks like i am, yeah


it's not a show stopper and i can work around it. i'm just curious.


if you put your (minimized) example on klipse, I can have a look


btw what is data-toggle?


it might be that i'm excluding cljsjs/react and including react-with-addons


are you using some sort of bootstrap jquery plugin? that would explain why it doesn't work


ah yes, the full component is a bootstrap dropdown


then that's the problem


bootstrap strikes again..


it's always tricky to mix jquery (and other direct dom manipulation libs) and react


bootstrap is fine, as long as you keep the javascript addons out of it


that makes sense. okay thanks for the help! i'll try to avoid the js side of bootstrap as much as i can.


I have two components A->B, I update the local state of A, and the :component-did-mount of B, that btw is not being mutated at all, is being called for every local state change of A. Is there any way around is, maybe there's a parallel function in reagent to om's om/factory?


can you share the code?


otherwise it's hard to guess where the error may be


I cant make a minimal example, but I can try In component A I have resizeable table that I define here

:component-did-mount (fn [this]
                           (r/set-state this  {:column-border-1 142
                                               :column-border-2 172
                                               :column-border-3 175
                                               :column-border-4 172
                                               :column-border-5 162
                                               :column-border-6 162
                                               :column-border-7 182
                                               :column-border-8 190}))
I resize them in component A with swap! this is the beginning of component B and in read-from-uri is a re-frame reaction that fetched data, but in general, I think :component-did-mound shouldn't be called more than once.
(defn search-query-component []
   {:display-name "search-query-component"
    :component-did-mount (fn [this]
                           (let [search-query-local-state-atom (r/state-atom this)]
                             (read-from-uri search-query-local-state-atom)
                              EventType/KEYDOWN #(cond
                                                   (= 32 (.-keyCode %)) (.preventDefault %)
                                                   (= 27 (.-keyCode %)) (close-all-shelves search-query-local-state-atom)
                                                   (= 13 (.-keyCode %)) (search-with-enter-key search-query-local-state-atom @(rf/subscribe [:search/queries]))
                                                   (= 8 (.-keyCode %)) (swap! search-query-local-state-atom assoc :backspace? true)
                                                   (= 46 (.-keyCode %)) ;;DELETE KEY
                                                   (swap! search-query-local-state-atom assoc :delete? true)
                                                   :else (when (or (:backspace? @search-query-local-state-atom)
                                                                   (:delete? @search-query-local-state-atom))
                                                           (swap! search-query-local-state-atom assoc
                                                                  :backspace? false
                                                                  :delete? false))))
                              EventType/CLICK (fn [ev] (if-not
                                                           (or (.-defaultPrevented ev)
                                                               (:datepicker-default-prevent @search-query-local-state-atom))
                                                         (close-all-shelves search-query-local-state-atom))))))


well, most of this code is not related. But as I mutate these :column-border-x vals, nothing is suspicius from the same(this) component, only in the components that the component is rendering


Ok a more basic question, I define a react-component with defn B... and I want to render within a component, so I call it from A via :render (fn[] (B)). But wouldn't it make more sense, to "manufacture" the component first, like (def b (B)) and render it then, so that rerender won't have any effect on nested components?


that solved it. Did this

(def manufactured-search-query-component
from its parent


hm that doesn't make a whole lot of sense to me but glad it works for zou


it makes perfect sense to me, because if you make a function call in render, it's going to get re-called on re-render. But if you call the function once in a def, then rerender won't recall that function.


that's not how reagent works, but glad you got it working that way


lol ok, my only alternative theory would be that Im forgetting to give r/create-class a react-key, therefore react doesn't know if it needs to rerender.


no if the child key is missing, it should still work but issue a warning


a couple of things about your code


i wouldn't use r/state-atom etc but just use a ratom bound in a closure instead


search-query-local-state-atom should be defined outside create-class, otherwise it won't rerender correctly


plus you're passing around the state atom, which makes things complicated


ahhh ok, I think I understand you. Don't know why this is needed but I've seen it in reagent before so I'll do that.


better to pass callbacks fns to the child components


reagent seems to give a local-state atom for free, wanted or unwanted. I notice that reagent users love global states for even the most trivial transient states, of course differs. Maybe swapping the local-state-atom is a bad idea all togeather?


in general, I strongly prefer a single global state atom whereever possible


for ephemeral state, however, a local atom bound in a closure is also a good option


I see it that a component should be reuseable dataprocessing engine, it takes data and renders some data. If a text fields needs to transact to global atom that the user pressed the delete key or the mouse is hovering a div, is adding complexity in my opinion. What should flow trough the components should be remote-data, processed remote data, user inputs etc. Of course this talk is more of a talk that's usually not connected to the reality of front-end development.


you can pass around cursors


that usually does the job for me


but yeah, everyone needs to find their own way of using React; reagent is pretty unopinionated by itself


don't forget there are huge advantages to having all (non-ephemeral) state in a single atom: you can introspect the state (e.g. with data-frisk), you can serialize it and send to the server if a bug occurs, you can spec it etc.


yes, I know the benefits of it but don't do it as much as I should. I can blame a bit om for making mutations a bit painful to add and me wanting fast feedback. But yes, I'll have to try the re-frisk, which I haven't done yet.