Fork me on GitHub
#reagent
<
2018-03-22
>
juhoteperi09:03:26

(js/console.log "cljs.core/partial" (= (partial println "foo") (partial println "foo")))
(js/console.log "reagent.core/partial" (= (r/partial println "foo") (r/partial println "foo")))

juhoteperi09:03:52

Real use could look like:

(defn foo-component []
  [input-component {:on-change (r/partial change-callback :foo) ...}])
Normal partial here would cause input-component to be re-rendered always as the on-change function identity could change each render

šŸ‘ 4
pesterhazy10:03:59

nice! And it only compares as equal if the arguments do I assume?

pesterhazy10:03:08

I guess the same could be accomplished with

(defn foo-component []
  (let [on-change (change-callback :foo)]
    (fn []
      [input-component {:on-change on-change ...}])))

juhoteperi09:03:26

(js/console.log "cljs.core/partial" (= (partial println "foo") (partial println "foo")))
(js/console.log "reagent.core/partial" (= (r/partial println "foo") (r/partial println "foo")))

juhoteperi09:03:52

Real use could look like:

(defn foo-component []
  [input-component {:on-change (r/partial change-callback :foo) ...}])
Normal partial here would cause input-component to be re-rendered always as the on-change function identity could change each render

šŸ‘ 4
mikethompson10:03:50

I'm kinda in shock that I haven't seen this before

mikethompson10:03:17

How did I miss this?

mikethompson10:03:28

Why wasn't I told? :-)

juhoteperi10:03:49

Haven't really used it myself

pesterhazy10:03:43

@mikethompson I know the feeling. Just when you thought that you've seen it all...

pesterhazy10:03:26

as far as I can see, it's similar to using a Form-2 component with a fn bound in a let though

juhoteperi10:03:13

(defn foo-component [{:keys [something another]}]
  [input-component {:on-change (r/partial change-callback something) ...}])

pesterhazy10:03:15

although.... if the arguments to the function stay the same, the child wouldn't necessarily rerender

pesterhazy10:03:30

I mean if the arguments depend on the props

juhoteperi10:03:52

In the example, if something doesn't change, the :on-change fn shouldn't change either

pesterhazy10:03:15

that's clever

mikethompson10:03:00

In re-frame terms, this old way:

(defn foo-component [{:keys [something another]}]
  [input-component {:on-change #(dispatch [:it-changed]) ...}])
becomes:
(defn foo-component [{:keys [something another]}]
   [input-component {:on-change (r/partial dispatch [:it-changed]) ...}])

pesterhazy10:03:55

true, it's a great fit for dispatch

pesterhazy10:03:43

well it won't work with on-change because you'd need the argument...

pesterhazy10:03:10

it would get added as a 2nd argument to dispatch

mikethompson10:03:10

Indeed. So more thought needed. But I like it.

pesterhazy10:03:07

it could be helpful as an optimization to prevent unnecessary rerenders

mikethompson11:03:52

Yes, exactly. But how to package it without confusing everyone. I look at things through the lens of "how much docs to explain this"

pesterhazy11:03:52

You could introduce a macro which reuses the same idea as r/partial: {:on-change (rf/dispatch-fn [new-text] [:it-changed new-text])}

pesterhazy11:03:50

rf/dispatch-fn being analogous to clojure.core/fn

pesterhazy11:03:36

the danger is that it become hard to grok what's going on behind the scenes

jmckitrick16:03:05

I have 2 components Iā€™m trying to import via shadow-cljs, after previously using the ā€˜double bundleā€™ method.

jmckitrick16:03:46

One of these components is accessed via [:> foo], while the other is [:> (.-default bar)]

jmckitrick16:03:33

Now that Iā€™ve switched the build to shadow-cljs, the first component does not work with either method.

pesterhazy16:03:40

try printing out foo to the console

pesterhazy16:03:08

these days I always inspect in the console first; it always gives you a first clue

pesterhazy16:03:42

but @thheller may have a better idea what's going on

thheller16:03:53

thats a good start. react component libs are bundled in a variety of ways and something its not exactly clear whether you are supposed to use default export or something else

jmckitrick16:03:59

Let me back upā€¦ once Iā€™ve required the componentā€¦ Iā€™m using a let binding to get a local name

thheller16:03:17

(js/console.dir foo) is also pretty useful for inspecting what you actually get

jmckitrick16:03:22

["react-avatar-editor" :as react-avatar-editor]

jmckitrick16:03:36

Itā€™s an empty object ATM šŸ˜‰

jmckitrick16:03:49

Let me try the original ns

thheller16:03:14

I get a function which looks like a normal react component

thheller16:03:53

(:require ["react-avatar-editor" :as react-avatar-editor]) then [:> react-avatar-editor ...]

jmckitrick16:03:02

Well, thatā€™s revealing. Both objects are empty.

pesterhazy16:03:16

what do you mean empty? {} or null

pesterhazy16:03:39

that's peculiar

pesterhazy16:03:56

how are you printing the object? console.log?

jmckitrick16:03:08

log says {} while dir shows nothing

pesterhazy16:03:49

I don't know then, except that that's not normal

jmckitrick16:03:03

ok, hold onā€¦ back to shadow

justinlee19:03:37

Has anyone ever managed to create a file input element in reagent that refuses to actually open the dialog box? I moved some code that used to work into its own file and now this happens. I cannot for the life of me figure out how I broke this.

jmckitrick19:03:17

I did one of these recently, but it didnā€™t break.

justinlee19:03:07

no nothing. itā€™s infuriating

manutter5120:03:06

If that happened to me I think my first try would be shut down the repl, lein clean and restart. Sounds like something's corrupted somewhere

pesterhazy20:03:24

Thatā€™s a good thing to try

pesterhazy20:03:09

Also could it be that a function call needs to happen in the same event loop tick as a user click?

pesterhazy20:03:36

A stab in the dark admittedly

jmckitrick20:03:41

@lee.justin.m What does the callback look like? Iā€™ve gotten the lambda wrong sometimes, and the event was never handled.

justinlee20:03:29

The dialog doesnā€™t even show so Iā€™m not getting that far

jmckitrick20:03:52

Is your event named correctly? case, etc?

jmckitrick20:03:13

Can you try in multiple browsers?

jmckitrick20:03:52

[:input {:type :file :accept "image/*"
               :style {:position :absolute
                       :top 0
                       :right 0
                       :width 65
                       :height 55
                       :opacity 0.0
                       :cursor :pointer}
               :on-change #(handle-file-change %)}]

manutter5120:03:07

@lee.justin.m You're talking about the browser's built-in file input, with the button you click to select the files, right? If that's not working, there's a good chance something corrupted in the browser itself -- a browser restart and/or hard cache reset might be in order.

manutter5120:03:32

Or if you have an :accept setting, check that for weirdness.

jmckitrick21:03:45

@lee.justin.m did you figure it out?

justinlee22:03:06

no. something very strange is going on here. iā€™m trying to reboot the improbability drive

justinlee23:03:35

@manutter51 @jmckitrick thanks for your help. the issue was that a back onclick handler in the parent div prevented the native widget from working. Iā€™m quite surprised by that, but maybe the click has to propagate all the way up to work (?)

justinlee23:03:03

(the real problem is that my hot reload environment was getting screwed up so i kept doing experiments that werenā€™t actually having any effect)

jmckitrick23:03:46

Glad you figured it out. Iā€™m also interested in what went wrong in your env, once you know.

justinlee23:03:38

okay this is the issue: i was using the the olā€™ ā€œhidden inputā€ trick. this worked fine before because the visible div button and the input were siblings. then i moved them into their own file and the input became a child of the div. you click on the div, it calls .click on the input, which of course then propagates the click back to the same click handler. i donā€™t know why this doesnā€™t cause an infinite loop--there may be some kind of code prevention in the browser for that.

justinlee23:03:10

the super confusing thing is that then when i made the input element visible so i could test the native button, it still didnā€™t work because of this infinite loop thing.