This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-09
Channels
- # beginners (41)
- # boot (4)
- # cider (36)
- # cljsrn (9)
- # clojure (365)
- # clojure-dev (1)
- # clojure-dusseldorf (1)
- # clojure-nl (1)
- # clojure-russia (3)
- # clojure-spain (1)
- # clojure-spec (19)
- # clojure-uk (1)
- # clojurescript (159)
- # code-reviews (7)
- # core-async (51)
- # cursive (2)
- # datascript (1)
- # datomic (1)
- # emacs (5)
- # figwheel (3)
- # hoplon (18)
- # incanter (1)
- # lein-figwheel (1)
- # leiningen (3)
- # lumo (145)
- # off-topic (26)
- # onyx (21)
- # re-frame (2)
- # reagent (45)
- # rum (4)
- # uncomplicate (10)
- # untangled (23)
- # yada (6)
Is this statement true: if a reagent component takes a callback as an argument, it will always rerender if that callback is an anonymous function?
Not true
(def myfn (fn [] (println "boom")) (defn c1 [] [c2 myfn]))
Technically myfn is an anonymous fn 🙂
I'm kidding of course, but what about the interesting case? Let's check
(defn foo [] (let [f (fn [] (println "foo"))] (prn @x f (= @x f)) (reset! x f) nil))
If you call foo twice, it will still return false
. So every time you create an anonymous fn, you get a new object that is not equal to the ones before
So I think that means that the statement is true, because props will always be different.
I see. Thanks for the answer! I suppose a form 2 component could be used to get around that.
See http://app.klipse.tech/?cljs_in.gist=pesterhazy/36b56d1bd8b424abef81adbb5a392d93&container=1
This shows that your suspicion is correct
Using Form-2 is an interesting workaround.
Although all of this only applies if you're not capturing any variables in the closure, in which case the inner component needs to be updated anyways
Hm, perhaps an option would be to ignore functions when determining whether or not to update? This does imply that the callback function will never change on the fly (at least if all other arguments remain the same)
that's not a warranted assumption though
because if you use any vars in the fn, it will change
True... another option would be to describe anonymous functions with a vector of a named function and the arguments that get passed into it.
I've updated the Klipse to include @mikethompson's suggestion: http://app.klipse.tech/?cljs_in.gist=pesterhazy/36b56d1bd8b424abef81adbb5a392d93&container=1
I think at this point it would be useful to look at your actual problem
because avoiding re-running component's render-fn is not a goal in itself
really the js/cljs part of react is fast, what you want to avoid is actual DOM manipulations, which don't occur in either outer1, outer2 or outer3 in my Klipse
Yes, you're right of course. Not very common for this to be a problem I suppose 🙂 It's more of a potential problem I saw, since making an interactive component generic (which pretty much demands callbacks) seems to mean opting out of utilizing ShouldComponentUpdate
it's great that you pointed out the issue, I wasn't aware of it actually
or maybe in the back of my mind but not clearly
can you explain what you mean by opting out of utilizing ShouldComponentUpdate?
I just meant that reagent uses identical?
to decide on a rerender inside the React method ShouldComponentUpdate
(at least that's what I assume, should probably read the source), so if identical?
always returns false, you're not really using ShouldComponentUpdate
ah so what you're saying is that one option would be to override should-component-update?
basically to only consider a subset of the props
Yes, but as you've said, assuming anonymous functions are always the same isn't quite valid
(defn renderer
[]
[:div
[:form {:method "post"
:enctype "multipart/form-data"
:name "uploadform"
:style {:font-size "18px"}
:action "/upload/afile"
}
[:input {:type "text"
:name "filename"}]
[:input {:type "file"
:name "filefield"}]
[:input {:type "submit"
:value "Upload"}]]])
(defn component
[]
(r/create-class {:reagent-render renderer}))
everything renders but the :enctype "multipart/form-data"
attribute, how would one push :enctype
attribute into the displayed form tag ?@urbank @pesterhazy related ..... https://github.com/Day8/re-frame/blob/master/docs/Performance-Problems.md#4-callback-functions
Can someone give me a bit more detail on the :on-change
line here
(defn input []
[:input {:type "text"
:value @state
:on-change #(reset! state (-> % .-target .-value))}])
on-change is a browser attribute set to a callback. The callback receives as its argument an event
The code sets state to (in JS) e.target.value
target referring to the input box, .value
its contents
.-
is js interop syntax for accessing properties
(-> % .-foo .-bar)
is equivalent to (.-bar (.-foo %))