Fork me on GitHub
#clojurescript
<
2023-01-31
>
manu10:01:25

Hi all, what is the best way to debug, inspect and access to the state of a component? (something like react developer tools) thx

p-himik11:01:00

You haven't mentioned the UI library that you're using. But I'm pretty sure that none of the existing libraries offer anything like that. You can use React DevTools with React wrappers just fine. And closest we have to CLJS state observation is re-frame-10x and re-frisk if you use re-frame.

manu11:01:58

At the moment I'm just trying https://github.com/pitch-io/uix

manu11:01:25

this is using state with the hooks, but i saw other libraries (as the old version of Uix) are using atom to manage state. but how you can see the state of the atom of the single component?

p-himik11:01:21

Since it's not even a wrapper, React DevTools should definitely be sufficient. No clue about the older version of Uix, but IIRC Reagent stores its atoms within the state of an instances, so those are also observable by React DevTools. I might be wrong though, it's been some time.

manu11:01:51

with new Uix version I can see the state but it's quite confusing (but better than nothing )

manu11:01:26

old Uix works like reagent if i remember well (it's been a while for me with reagent), and i cannot access to the component state (that basically are atom)

p-himik11:01:54

Yeah, nah - React DevTools isn't really useful when trying to read Reagent state. It's either not that (in the case of r/with-let) or attempts to study it, assuming I found the correct thing, lead to time outs of React DevTools.

manu11:01:09

may i ask which library are you using?

manu11:01:59

i'm looking around the best option but it's quite hard to decide

p-himik11:01:24

I use re-frame.

p-himik11:01:45

What "the best" means depends on you though, so no idea whether it's even suitable for you.

p-himik11:01:25

Back in the day when I was choosing what to use, I spent pretty much a week reading about all available options and trying the most promising things out to see how they felt.

manu11:01:14

long time ago for new projects i used reagent + reframe and i didn't regret it

manu11:01:42

now i should convert react code into clojurescript

manu11:01:37

and i saw that there are more options than 6 years ago 😅

manu11:01:09

yeah i think i should spend more time studying

manu11:01:44

thx 🙂

👍 2
Illyria14:01:17

How do I update a text field with value in a form only on button press without having to store two values separately? Is it possible? My code:

(defn update-text-on-press []
  (let [form-value (r/atom "")
        text (r/atom "")]
    (fn []
      [:div
       [:input {:type "text" 
                :value @form-value 
                :on-change #(reset! form-value (-> % .-target .-value))}]
       [:button {:on-click #(reset! text @form-value)} "Update"]
       [:p @text]])))

p-himik14:01:10

The #C0620C0C8 channel is more suitable for such questions.

p-himik14:01:27

You can make :input an incontrolled component and access its internal value when clicking the button.

p-himik14:01:53

And you can access that rendered :input from within the :on-click handler by using React refs.

pez15:01:07

Here's a mystery to me: I'm using the js/MediaRecorder stuff to record video. It gives me back video data in chunks. Then I can construct a js/Blob to concatenate the chunks to a Blob of data (js/Blob. chunks #js {:type <mime-type>}) That blob is my video. If I conj the chunks on a vector and then give that vector to the constructor the data gets corrupted. If I convert the vector of chunks (clj->js chunks) and give that to the constructor, the data also gets corrupted. But if I use a JS array and mutate it with (.push js-chunks) as the data comes in, then the resulting blob is just fine. Why doesn't it work with a cljs vector, not even if I cast/convert it to a JS array?

p-himik15:01:01

What's the type of a chunk?

pez15:01:21

It's a js/Blob too.

p-himik15:01:29

Weird. clj->js does exactly that to vectors - it creates an array and then calls .push on it for every element. Maybe there's something terrible in your codebase that extends the IEncodeJS protocol to blobs. Apart from that, can't imagine what's going wrong. Would be curious to poke around if you can create an MRE.

p-himik15:01:45

But also, it should just work for CLJS vectors since they're JS iterables.

pez15:01:25

That was my assumption. I'll create a repro. Might find out what I'm doing wrong when I do that. That often happens to me.

pesterhazy16:01:17

I usually see clj->js as an anti-pattern, as it's a bit magical and often not the most performant solution

pez16:01:26

I only did that because I started to suspect that my cljs vector was a problem.

pez16:01:53

But, generally I use clj->js all over the places. 😃 Maybe I shouldn't.

pez16:01:18

I don't like to have to mutate this object in my implementation here... It's not cool.

pesterhazy16:01:22

Gotcha. You can also create an array conventiently via into-array

pesterhazy16:01:11

clj->js "helpfully" does more, like recursively converting elements, which can be risky

p-himik16:01:13

You shouldn't. :) Most of the time, you can do just fine without. E.g. creating an array in one go from an iterable (e.g. a vector): (js/Array.from v). You can even map a function over it while converting: (js/Array.from v inc).

pez16:01:52

For arrays this is the first time I have even tried clj->js, I think. It's usually maps I do it with.

p-himik16:01:17

I don't think there's anything that's that easy for objects, but it's like 3 lines of CLJS code - I'd put it into some util NS and use it everywhere.

pez16:01:30

It didn't work using to-array nor js/Array.from on the vector either.

pesterhazy16:01:09

I'd probably reach for something like

cljs.user=> (apply js-obj (mapcat identity {"a" "b", "c" "d"}))
#js {:a "b", :c "d"}

🙏 2
p-himik16:01:10

@U0ETXRFEW I'm now dubious it has worked with a manual .push. :) Maybe a fluke?

p-himik16:01:56

If converting a map to a JS object is in any performance-sensitive area, I'd go with reduce-kv and gobj/set to avoid building an extra coll.

👍 2
pez16:01:56

Yes, it is crazy. I can repro it perfectly in our app here.

pez16:01:18

The difference is in ondataavailable on the MediaRecorder instance. If I conj the data on a vector, I am screwed. If I .push it on an array, things are dandy. (In case this wasn't clear.)

pesterhazy16:01:33

That really sounds like something else is going on

pesterhazy16:01:48

You can 100% store js objects in a vector

p-himik16:01:52

Is that vector in an atom at least? I hope you don't just (conj v blob) and call it a day. :D

pesterhazy16:01:05

I was thinking the same ^^ 🙂

pez16:01:00

It's a re-frame db.

p-himik16:01:37

So in each data available event, you dispatch a re-frame event that adds a blob to some vector in the app-db? And when the recorder is done, presumably you dispatch another event that gets all those blobs and does something to them? Or do you, instead of using blobs as the medium, actually use JS events?

p-himik16:01:51

Although it shouldn't be the crux of the issue because MediaRecorder has nothing to do with React. But I'm very wary of using raw JS events in general.

pez17:01:15

It wasn't such a mystery after all. When I was to show @U06F82LES how it didn't work with vectors, it worked. No idea why it didn't when I switched to an array... But anyway, now functional again. Phew!

p-himik17:01:10

Maybe there's some issue with code reloading?

p-himik17:01:13

Or caching.

pez19:01:29

Could be, I have two phone clients and three desktop browsers, sometimes I lose track of where my REPL runs.

pez19:01:48

It started with me using nil for my chunks and assuming conjing on that would append to the end. Then, without realizing that this wasn't the case, I tried with a vector because I felt sure that would work. But at a point I had a two stashes I could switch between and that reproduced the mystery. When showing @U06F82LES the problem I decided to not use the stash, but instead change it to a vector while we were pairing. I think I avoided some funny edit that I had in my vector stash.