Fork me on GitHub
#reagent
<
2022-02-27
>
Chase16:02:00

I'm working through a reagent tutorial and trying to clarify for myself when I need to wrap a function call anonymously or not. Like with:

...
  [:img {:src (get-in @state/gigs [id :img])}]
  [:div.price (* (get-in @state/gigs [id :price] quant]
  [:btn {:on-click #(do-something)}]
My current understanding is the img and price elements evaluate the functions immediately on initial render right? But you need to use the anonymous function for the button click event because otherwise it would call that do-something function immediately whether the button was clicked or not. You want to feed :on-click a function, not the result of the function so you must wrap it into an anonymous function?

p-himik17:02:38

Not on initial render but on every render. Hiccup is just nested vectors and attribute maps. The view function is called when there's a need to render the component, the vectors are created, and then Reagent turns them into React elements. > But you need to use the anonymous function for the button click event because otherwise it would call that `do-something` function immediately whether the button was clicked or not. It will be called if you use (do-something). It will not be called if you use it as do-something. Again - at this point, you're just creating vectors, there's no magic here. Neither React nor Reagent call functions that you pass to :on-click and similar handlers on render. You must pass :on-click a function. In this case, the function should accept one argument - the event. "Should" and not "must" because JS allows you to pass N values to a function with M arguments where N != M. The only reason to use #(do-something) instead of just do-something above is to make it clear that you ignore the vent. To make it even more clear, you can instead write:

:on-click (fn [_event] (do-something))

Chase18:02:45

Ok, thank you so much. And that _event is saying you are ignoring an Event object that is "created" (?) when you click the button. I also want to review that more. Events are created in js when you take an action and we can access those Event objects for the information they contain? This is where my lack of js/web dev expertise is showing I think.

Chase18:02:05

And is that Event object also what is getting accessed when I see things like (-> .-target .-value %) in cljs code right?

lilactown18:02:24

Reagent wraps react. For event handling you should refer to their docs https://reactjs.org/docs/events.html

Chase18:02:16

Ahh, of course. Ok. I knew it was wrapping React just didn't take that the extra step in realizing React has it's own events that Reagent would use over plain js

Chase18:02:30

Ahh yes, right in the docs I see calls to e.target (but nothing to e.target.value)

p-himik18:02:44

That _event is just a regular argument. The _ in front is a common approach to denote unused named variables that some, if not most, IDEs support and don't highlight such usages as unused by mistake. I can also suggest reading MDN resources for anything web-related and avoiding W3Schools altogether.

Chase18:02:17

Yep, I did know that much thankfully. haha And so when I just console.log out that event to see what it is I'm getting a #object[SyntheticBaseEvent [object Object]] which is what those react docs are discussing

Chase18:02:36

And of course I can see the .target field of that SyntheticBaseEvent but within that I don't see a .value field so I'm still not sure where that is coming from.

p-himik19:02:25

What value would you expect a button to have? (assuming you're still looking at that :on-click event handler) .-value only exists for input fields.

Chase19:02:15

Ahh, of course. Now I feel dumb. I've been rotating through the React docs, Reagent docs, and the tutorial. I was looking at an input field when that came up but was inspecting a button when I got back to it.

p-himik19:02:20

Happens. :)

nixin7220:02:58

Has anyone here had luck using the Monaco editor from ClojureScript with Reagent? I wanted to mess around with it, but it appears to be structured in a way that makes it not very straightforward. All I could find about it was a reddit post from 3 years ago saying it wasn't going to be a pleasant experience and an archived cljs library for using it that's not been touched in a while.