Fork me on GitHub
#reagent
<
2018-08-03
>
rnagpal12:08:59

I can understand how ratoms knows about the components which deref it

rnagpal12:08:19

But I dont see the code of how the react component is actually refreshed (actual call to react api)

rnagpal12:08:54

I just know of two ways the component can refresh 1) Changing of props 2) Setting the state The child components can refresh as new props are passed, but I dont see a call to React’s setState anywhere in reagent in order to refresh the component whose state changed

athomasoriginal17:08:40

Hey all, curious about passing children down to a component. For example, in React I would write something like this:

const Container = (props) => (
  <header>
    { this.props.children }
  </header>  
)
yet in clojure, I might write the above like this:
(defn Container
  [props & children]
  [header
    children])
Its interesting because React itself gives props which has children as a property. Is my clojure example the agreed upon way or should I be doing something like r/props

justinlee17:08:03

@tkjone there isn’t really a distinction between children and props in reagent. technically, all parameters are passed as children, unless the first parameter is a map, in which case that parameter is passed as props and the remainder as children

justinlee17:08:23

the distinction made more sense in JSX because of its syntax

justinlee17:08:32

the only time it matters is when you are doing interop

justinlee17:08:24

even in react, there’s the so-called “slots” pattern where you pass children under named props. i think the pattern you have above is the normal one where you don’t care about your children and just want to pass them through. https://daveceddia.com/pluggable-slots-in-react-components/

athomasoriginal17:08:43

True. I suppose I was curious if r/props would be used in an instance like this as a way to access the children, but I think you are right that that is because of how the JSX confuses this a little with its syntax

justinlee17:08:54

yea there’s no point in doing that. afaick, you only need r/props and r/children in form-3 lifecycle methods where you don’t have access to the render-function parameters.

justinlee17:08:34

the this.props.children is a convention entirely introduced by the JSX compiler. react doesn’t know about or treat it differently, though all react libraries generally abide by this convention.

athomasoriginal17:08:16

Cool. Thanks for clearing that up!

lilactown17:08:12

@lee.justin.m I’m not sure that’s quite correct. the signature for createElement is: createElement(component, props, children) and the corresponding function component will receive it’s children in a children property on the props object, irrespective of using JSX or not

lilactown17:08:51

reagent paints over this and let’s us pretty much ignore the normal props object that React uses

justinlee17:08:06

@lilactown ah! I stand corrected

justinlee17:08:20

I’m not sure if I understand why they did that

justinlee17:08:38

I’m 99% sure that there isn’t any difference in passing children that way vs manually but that’s interesting

justinlee17:08:50

an by manually i mean using the slots pattern i linked to above

lilactown17:08:12

some of it might just be ergonomics when writing non-JSX code that carried over

lilactown17:08:19

creating trees of components is visually nicer when you don’t have the trees inside of a bunch of curly braces

lilactown17:08:42

I’m spending some time using raw React in CLJS right now and I kind of appreciate it 😛

justinlee17:08:45

yea i looked at the source. it just copies them over to props.children and deals with variadic #s of children

lilactown17:08:17

I feel like I understand the discussion up to when sebmarkbage comes in lol

justinlee17:08:28

that’s exactly what i was thinking

justinlee17:08:39

that guy is so effing smart and he’s like 12 years old

justinlee17:08:07

there’s some discussion of hoisting that i’m not following here

justinlee17:08:50

actually i’m confusing him with the other react sebastian

lilactown18:08:05

yeah I think you’re thinking of the babel guy

lilactown18:08:02

the overriding of children passed into props is interesting

lilactown18:08:17

I’m wondering, for my own uses, if I’ll get in trouble if I just stop dealing with the fact that createElement is variadic and pass in children to the props object directly

justinlee18:08:30

looking at the code, I don’t think createElement does anything to props.children if you only pass 2 arguments

rnagpal18:08:42

I think if its type 1 component and the first element is a map, it will be passed as a props, else props will be nil

rnagpal18:08:32

Ultimately reagent calls createElement(tag, props, children...)

rnagpal18:08:01

so props is null in case the first arg is not map

rnagpal18:08:53

In case of type 2, the props passed are {"argv" : [full vec]}

rnagpal18:08:09

This is just based on the abovr lines

rnagpal18:08:54

Please correct me if I am wrong

rnagpal18:08:04

Log story short @tkjone as @lee.justin.m mentioned, you dont need to worry about props

rnagpal18:08:18

until you are working with a type3 components

rnagpal18:08:43

when you need props in componentWill/componentDid methods

rnagpal18:08:24

Just pass args as you are calling a function

athomasoriginal18:08:08

Good point. Thanks!

dijonkitchen18:08:30

I’ve looked online and on slack, but can’t find docs on how to pass components as props to another component. In React JSX:

<FormControlLabel control={<Checkbox value="checkedC" />} label="Uncontrolled" />
What I’m trying in reagent:
[mui/form-control-label {:label "Mailing address is same as above"
                                :control mui/checkbox}]
Error:
Warning: Failed prop type: Invalid prop `control` of type `object` supplied to `FormControlLabel`, expected a single ReactElement.
    in FormControlLabel
Anybody see what I’m doing wrong?

justinlee18:08:46

@rnagpal it looks like form-1 and form-2 components work the same:

(defn form1 [a]
  [:div
   [:div "form1 props = " (pr-str (reagent/props (reagent/current-component)))]
   [:div "form1 children = " (pr-str (reagent/children (reagent/current-component)))]])

(defn form2 [a]
  (fn [a]
    [:div
     [:div "form2 props = " (pr-str (reagent/props (reagent/current-component)))]
     [:div "form2 children = " (pr-str (reagent/children (reagent/current-component)))]]))

(defn test-component
  []
  [:div
   [form1 {:a 1}]
   [form1 17]
   [form2 {:a 1}]
   [form2 17]])
renders
form1 props = {:a 1}
form1 children = nil
form1 props = nil
form1 children = [17]
form2 props = {:a 1}
form2 children = nil
form2 props = nil
form2 children = [17]

lilactown18:08:36

@dijonkitchen it looks like what you’re passing in is the React component, when what it expects is a React element

justinlee18:08:43

@dijonkitchen you need to run the hiccup through as-element

lilactown18:08:42

☝️ {:control (r/as-element [mui/checkbox {:value "checkedC"}])} as an example

lilactown18:08:53

:thinking_face: I wonder how future-proof create-react-class is </random-thought>

justinlee18:08:02

probably pretty future proof. at any rate, you can create and manipulate es6 classes directly in cljs

lilactown18:08:16

yeah it’s just real obnoxious to write.

justinlee18:08:58

yea i mean say i think create-react-class is pretty generic

lilactown18:08:38

I’m thinking real hard right now about how to take advantage of suspense when it comes out, and other future React improvements. wondering if basing a new lib on create-react-class might be a mistake

rnagpal18:08:57

You are right @lee.justin.m Form1 & 2 passes props as argv

rnagpal18:08:22

(reagent/props (reagent/current-component)) and (reagent/children (reagent/current-component))

rnagpal18:08:45

are just helpers to extract the props and children one expects

👍 4
justinlee18:08:33

@lilactown you can always remove it and just create the es6 classes yourself if it ever gets in the way. just don’t expose it to your users. i.e., in reagent, you could remove create-react-class and nobody would know except for dependencies

justinlee18:08:49

* at least I think

justinlee18:08:14

suspense is going to be freaking awesome. i cannot wait for that. it will solve so many of my problems

💯 4
lilactown18:08:42

true, there are just certain things that are very ergonomic to do with create-react-class that are a HUGE PITA with raw prototypes

lilactown18:08:03

like automatic method binding

lilactown18:08:50

mainly I’m just trying to decide how lazy I am now vs. how frustrated I’ll be later 😛

justinlee19:08:12

hard work pays off over time. procrastination pays off right now.

🍺 4