Fork me on GitHub
#reagent
<
2018-04-03
>
borkdude15:04:07

It’s not recommended to pass a ratom as an argument down to another component, right?

gadfly36115:04:39

I pass app-state ratom as first argument to most all of my components (when using vanilla reagent)

pesterhazy15:04:49

nothing wrong with passing around ratoms

borkdude15:04:49

I mean, how does that affect shouldComponentUpdate?

borkdude15:04:14

don’t atoms carry functions (add-watch callbacks) which cannot be compared properly?

borkdude15:04:32

or does it implement some IEquiv thing

pesterhazy15:04:49

if the ratom itself doesn't change, no rerenders

athomasoriginal16:04:04

What are people using for testing reagent components? I come from a JS background, specifically Jest, and while I know that CLJS does not have a tool like Jest, I was hoping to learn how things like snapshots or enzyme are being done in CLJS

athomasoriginal16:04:05

@pesterhazy is there an understanding of why this is? Or is it just the tooling/ecosystem is just not there yet?

pesterhazy16:04:45

Probably that plus a certain vague idea that unit testing UIs is expensive and brittle (maybe even pointless), paired with a REPL culture (as opposed to testing culture)

pesterhazy16:04:05

Or just plain arrogance, or the fact that Clojurians rarely work in large teams?

gadfly36116:04:49

@tkjone I think many who do test, test event handlers and helper functions instead of components themselves .. since those can be pure and test runs will be very fast. There is lein-doo and cljs-react-test .. also etaoin that can help with component or integration tests, but it isn't a cljs standard to test components yet

pesterhazy17:04:19

Integration testing (using selenium etc.), IMO the most useful way to test UIs, is a good albeit brittle option and doesn't require digging into React internals.

👍 4
gadfly36117:04:20

Personally, I like the clojure proper tools for testing better than clojurescript (better emacs integration etc) .. so I put all of my handlers in .cljc files and run with lein test

gadfly36117:04:36

@pesterhazy @tkjone To piggie back on pesterhazy, then etaoin is a great choice .. like selenium, but written in clojure (and very active development)

pesterhazy17:04:30

I think JavaScript developers can sometimes go overboard when it comes to testing, but clearly the tools available in pure JS land are superior

pesterhazy17:04:12

Though this superiority is bought at the price of high tooling complexity

lgessler22:04:02

Hi all, I'm passing an element through a prop and I'm getting an error I don't understand (I'm using a Material-UI cljs wrapper). This is JS code I'm trying to imitate that demonstrates how the element is passed into the prop (code omitted for brevity):

js
  render() {
    const actions = [
      <FlatButton/>,
      <FlatButton/>,
    ];

    return (
      <div>
        <Dialog
          actions={actions}
        >
          The actions in this window were passed in as an array of React objects.
        </Dialog>
      </div>
    );
  }
I tried to translate this code into cljs (irrelevant code omitted, again):
clojure
(defn- new-project-dialog []
  (let [actions [:div
                 [ui/flat-button {:label "Create"
                                  :primary true
                                  :on-click close-dialog}]
                 [ui/flat-button {:label "Cancel"
                                  :primary false
                                  :on-click close-dialog}]]]
    [ui/dialog {:actions (r/as-element actions)}
     "test 1 2 3"]))
Note that I had to add the :div as a first element in the vector, instead of just leaving it as a two-item sequence with both of the elements being components. This produces the correct result, but I'm not exactly sure why I had to add the :div. I think it must have something to do with how I call r/as-element on actions, which admittedly I have just copy pasted without understanding. Is there a more direct way of translating the JS code, or is this something that is unavoidable with reagent?

justinlee22:04:27

@lgessler I suspect that the actions prop wants a javascript array of elements. so you probably need to run as-element on each of the FlatButtons and then put them in a js array

👍 4
justinlee22:04:57

as opposed to trying to run a cljs sequence through as-element

lgessler22:04:12

@lee.justin.m That did the trick--thank you. Modified code for posterity:

(js/Array.
                 (r/as-element [ui/flat-button])
                 (r/as-element [ui/flat-button]))

👍 4
mikerod23:04:45

@lgessler you could also use

mikerod23:04:49

#js[(r/as-element [ui/flat-button])
    (r/as-element [ui/flat-button])]

👍 4
mikerod23:04:31

Or

(cljs->js [(r/as-element [ui/flat-button])
           (r/as-element [ui/flat-button])])
In both cases, it may be a little less interop’y.

lgessler23:04:36

ah thank you!! i'm never pleased to write js/.... Thanks for the tip 🙂

4
pesterhazy08:04:47

AFAIK #js[1 2] or (array 1 2) is preferable to clj->js

mikerod11:04:14

Yeah I’d say so

mikerod11:04:19

clj->js is meant for deeper conversions. I meant to point that out that it isn’t as good for making just a flat js array like this. #js is likely the fastest option. But good point on array fn too.

lgessler15:04:21

Didn't know about the array function, thanks @pesterhazy

pesterhazy15:04:58

There's also into-array, which is very useful

pesterhazy15:04:12

clj->js should be avoided when possible

mikerod15:04:37

Yeah, I should have been clearer on that

pesterhazy15:04:58

Wasn't meant as a criticism 🙂

pesterhazy15:04:05

Sorry if it come off that way

mikerod15:04:11

cljs->js is a brute-force deep-walking thing. I think it’s best to stick to functions that are more specific to the desired goal in these cases

mikerod15:04:55

Oh, it’s fine. I didn’t think about it in a negative way.