Fork me on GitHub
#reagent
<
2018-04-29
>
lilactown16:04:07

[(r/adapt-react-class DragDropContext) ... 
  [(r/adapt-react-class Droppable) ...
    (fn [pr sn]
      (r/as-element [:div ...]))]]
@lwhorton

lwhorton16:04:57

☝️ this works, except that because you’re returning a fn (instead of a vector with a component in the first index) now reagent atom derefs no longer trigger a rerender. i guess that’s a different problem, though

lilactown16:04:03

that is correct. I have not come up with a solution for that yet

lilactown16:04:34

if you do, let me know! I’m working on a lib for working with React 16 context and it’s a problem

lwhorton16:04:04

hmm.. yea i’ll have to dig around. I wonder if it has to be lib-specific with some sort of “force rerender” option. or maybe I can wrap my inner fn with r/create-class and do a manual setState somewhere?

lilactown16:04:05

I’m not familiar with how exactly Reagent executes the re-rendering, so I’m not sure

lilactown16:04:55

what I’ve done so far is basically keep the render-fn components as “stateless” leafs that only depend on their props & value(s) passed in through the render-fn

lilactown16:04:49

but that probably isn’t very convenient when using e.g. react-drag-drop

lwhorton16:04:43

yea it’s a problem as soon as anything inside a drag-n-drop needs to modify state via some button, for example

lwhorton16:04:10

using an on-click to reset an r/atom won’t trigger a rerender

lilactown16:04:46

you could deref the atom above the Droppable 😅

lwhorton17:04:53

hah i hadn’t thought of that

lilactown17:04:59

I find myself doing this kind of thing a lot:

(defn component [props & children]
  (into [:div "a thing"] children))
so that I can pass arbitrary number of children into a component

lilactown17:04:08

is there a better way to do this without having to use into everywhere?

reefersleep18:04:05

well, you could just [:div "a thing" children]? Or perhaps, that’s not what you’re asking? 🙂

pesterhazy18:04:42

I use something along the lines of ...

(defn only-child []
  (let [children (r/children (r/current-component))]
    (when (not= (count children) 1)
      (throw (js/Error. "Only one child allowed")))
    (first children)))

(defn authwall-ui []
  (if authenticated?
    (only-child)
    [:div "Not authenticated"]))

👍 4
pesterhazy18:04:02

Then you can use the authwall wrapper by passing in another hiccup form:

pesterhazy18:04:27

[authwall-ui [content-ui]]]

pesterhazy18:04:53

(I use use the -ui suffix to man "this is a reagent component")

lilactown18:04:10

@reefersleep it would get passed in as e.g. [:div "a thing" [[:div "another thing"]]]

lilactown18:04:36

which is not valid hiccup

reefersleep20:04:53

True that. I’ve put seqs at the end of hiccup vectors, though; [:div 1 (list 7 3 4)] is valid hiccup. Don’t know if that helps you 🙂

reefersleep20:04:53

You’re doing & children in your arguments definition. That means that it is a list, and not a vector. You should be able to put it at the end of a vector literal. I’m doing the exact same thing in my code 🙂

lilactown20:04:40

it gives me warnings/errors about key prop

reefersleep14:04:36

oh yeah, but that’s nothing to do with the distinction between vector/list

reefersleep14:04:41

For some reason (that I have inklings about, but no true knowledge about), React likes to be able to distinguish between individual elements of a list via their key property. I think that is what is meant by those warnings, anyway.

reefersleep14:04:02

I often define a simple function for adding the keys in my reagent projects:

reefersleep14:04:56

(defn add-react-keys
  “Assigns unique ‘key’ props to the ‘components’ seq elements.
  React gives a ‘warning’ if each element of a seq does not have a unique ‘key’ prop. ”
  [components]
  (map (fn [component]
         (with-meta component {:key (random-uuid)}))
components))

reefersleep14:04:53

You could also do (map-indexed (fn [index component] (with-meta component {:key index})) components)

reefersleep14:04:10

Also, there’s a shorthand for adding the meta data

reefersleep14:04:44

(map-indexed 
  (fn [index component] 
    ^{:key index} component)
  components)

reefersleep14:04:10

If you’re using a library that does animations on your list, however, you need to identify your list elements uniquely and persistently for the transitions to work correctly. But don’t worry about if you aren’t using such a lib.

reefersleep14:04:03

And yeah, it sucks that you have to call add-react-keys everywhere, just as it sucks to call into everywhere. Too bad

reefersleep15:04:29

You could write a macro to handle it for you…

reefersleep15:05:03

@U4YGF4NGM (just want to make sure you get this)

lilactown15:05:14

yeah, thanks. I just decided to keep using into 😛

lilactown18:04:34

@pesterhazy I specifically want to be able to pass in an arbitrary amount of children, though

pesterhazy18:04:06

you'll need into then

😿 4
lilactown18:04:18

just published a lib for easy use of React’s new context API: https://github.com/Lokeh/reagent-context ⚛️ 🎉

lilactown19:04:58

and if anyone can figure this out it’ll really go from good to great 😅 https://github.com/Lokeh/reagent-context#gotchas

lilactown19:04:08

iiinteresting. the fact that ratoms aren’t bound inside of render functions does seem to be simply because they’re not used in a [component …] form

reefersleep20:04:53
replied to a thread:which is not valid hiccup

You’re doing & children in your arguments definition. That means that it is a list, and not a vector. You should be able to put it at the end of a vector literal. I’m doing the exact same thing in my code 🙂