Fork me on GitHub
#reagent
<
2018-02-22
>
donmullen15:02:19

I’ve been able to replicate this dx-react-grid code (https://github.com/oliversturm/demo-dx-react-grid-clojurescript/blob/master/src/demo-dx-react-grid-clojurescript/core.cljs) and trying to extend to track row selection with <Table rowComponent={TableRow}/> from the example at the bottom here: https://devexpress.github.io/devextreme-reactive/react/grid/docs/guides/fundamentals/. New to React - and not sure how to translate this code

const TableRow = ({ row, ...restProps }) => (
  <Table.Row
    {...restProps}
    // eslint-disable-next-line no-alert
    onClick={() => alert(JSON.stringify(row))}
    style={{
      cursor: 'pointer',
      ...styles[row.sector.toLowerCase()],
    }}
  />
);
to reagent. Thoughts?

justinlee16:02:19

that should translate pretty well. i think you can just define TableRow as a defn which returns [:> js/dxobject.Table.Row {props here}]

donmullen16:02:32

Hmm.. I’m a beginner - not sure how to interpret js/dxobject.Table.Row …?

justinlee16:02:06

oh sorry. so somehow you have to import the library into your cljs code

justinlee16:02:49

if you include it via a script tag or using :foreign-libs, there will be a global object somewhere that has all the goodies hooked on it. i don’t know what that library uses.

justinlee16:02:09

if you use something like shadow-cljs, it will get imported with its own namespace

justinlee16:02:18

i’m not sure how you are importing

donmullen16:02:41

@lee.justin.m - I’m using shadow-cljs — and have pulled in the npm libraries - and can access Table via ["@devexpress/dx-react-grid-bootstrap3" :refer [Grid Table TableHeaderRow TableSelection]]

donmullen16:02:19

not sure about Table.Row

justinlee16:02:42

okay so you’ll do something like [:> Table.Row {props}]

justinlee16:02:38

when you import Table, it is a javascript object. the clojurescript language allows you to stick dots in the middle of symbols and it just works (basically the dotted code just gets passed directly into javascript).

justinlee16:02:48

Table.Row is just accessing the Row prop from the Table object

donmullen16:02:41

And Table.Row is also a class? I’m converting Table via

(defn factory-apply
  "A function for wrapping a js React class in a factory."
  [class]
  (fn [props & children]
    (apply js/React.createElement
      class
      props
      children)))

donmullen16:02:56

But doesn’t work for Table.Row

justinlee16:02:15

try (.-Row Table)

justinlee16:02:23

maybe the dotted notation doesn’t work

donmullen16:02:26

Thanks - trying that… And yeah - I am using fulcro - but the original sample was in reageant 🙂.

justinlee16:02:55

okay yea so forget all that stuff about [:>...] because that’s reagent specific

donmullen16:02:14

Yeah - I knew that much from your article 🙂.

Tim Wade18:02:27

@lee.justin.m I'm just follow up from yesterdays conversation in #clojurescript , moving in here

Tim Wade18:02:52

I'm trying to understand why when I mutate the object I'm storing in my atom there, it's doesn't render the updated value in the UI component. If I "touch" the atom by also inserting some random data in it, it works

Tim Wade18:02:46

I'm assuming that since the object is preserved, it's just mutated, it's seen as equivalent - is there a pattern for dealing with something like this?

justinlee18:02:21

yea that what i would expect but i’m trying to think about what the “right” way to fix it is. the set! doesn’t change the actual atom

justinlee18:02:55

right. so the set! alters something deep inside the data object, but react will do a shallow compare on data, which of course looks like it hasn’t changed

justinlee18:02:44

here is what I would do: I would just store the frequency as a clojurescript inside the reagent/atom directly. then I would consider doing an add-watch on the atom and doing the set! there so that they are always in sync. you’ll need to remove-watch when the component unmounts too. now, when you update the frequency, your component will update and so will the javascript library

justinlee18:02:21

i suspect you can use a reaction or maybe the track function. but that stuff is sadly undocumented and I do not know how to use it practically. i feel like this is a perfect case for some of that functionality

Tim Wade18:02:39

Oooh, many thanks!

justinlee18:02:19

you can also just do it the easy way: instead of storing a random number, store the frequency in the atom and then do the set! code right next to it

Tim Wade18:02:29

I will play around with that! If I find something that works that's undocumented, I'll try to help document it 😉

Tim Wade18:02:05

Ah yeah I thought about doing that, but something about that made me think, I'm doing this wrong ™️

justinlee18:02:11

this is what i’ve collected from the realese notes

Tim Wade18:02:43

😻 this is great!

justinlee18:02:43

storing it twice is a code smell yea because what if they get out of sync. on the other hand, sometimes quick and dirty works for simple code.

justinlee18:02:12

this is a little of the blind leading the blind thought 🙂

Tim Wade18:02:17

It will....but I plan on having a lot more such things 😉

justinlee18:02:25

anyway i need to step out for a bit but good luck and let us know how it goes

Tim Wade18:02:26

Not at all....very enlightening!

Tim Wade18:02:37

I will! And thanks once again!

justinlee19:02:24

@hello721 another way to keep things in sync is to use a form-3 component and use :component-did-update and :component-will-mount. Basically, your outer component is the viewable UI and has frequency as a cljs structure in an atom. then you render the form-3 component and pass frequency as a prop. the form-3 component will own the sound generating stuff and will update it when new props come in

justinlee19:02:30

that’s much much simpler and better contained

Tim Wade19:02:00

@lee.justin.m interesting! I'll have to do some research into form-3 components, but that does sound very promising!

justinlee20:02:16

also described in that gist i sent you and also in the /docs folder of reagent github. read the react docs too if you’ve never used before.

Tim Wade20:02:40

Will do, thanks!