chefcurry7 chefcurry7 - 2 months ago 24
React JSX Question

Pass react component as props

Lets say I have:

import Statement from './Statement'
import SchoolDetails from './SchoolDetails'
import AuthorizedStaff from './AuthorizedStaff'


const MultiTab = () => (
<Tabs initialIndex={1} justify="start" className="tablisty">
<Tab title="First Title" className="home">

<Statement/>
</Tab>
<Tab title="Second Title" className="check">
<SchoolDetails/>
</Tab>
<Tab title="Third Title" className="staff">
<AuthorizedStaff/>
</Tab>
</Tabs>
)


Inside the Tabs component
this.props
has the properties

+Children[3]
className="tablist"
justify="start"


Children[0] (this.props.children) will look like

$$typeof:
Symbol(react.element)
_owner:ReactCompositeComponentWrapper
_self:null
_shadowChildren:Object
_source:null
_store:Object
key:null
props:Object
ref:null
type: Tab(props, context)
__proto__
Object


Children[0].props looks like

+Children (one element)
className="home"
justify="first title"


Finally Children object looks like (this is what i want to pass):

$$typeof:Symbol(react.element)
_owner:ReactCompositeComponentWrapper
_self:null
_shadowChildren:undefined
_source:null
_store:
key:null
props:Object
__proto__:Object
**type: function Statement()**
ref:null


The question is this, if I rewrite MultiTab like this

<Tabs initialIndex={1} justify="start" className="tablisty">
<Tab title="First Title" className="home" pass={Statement}/>


<Tab title="Second Title" className="check" pass={SchoolDetails}/>



<Tab title="Third Title" className="staff" pass={AuthorizedStaff}/>


</Tabs>


Inside the Tabs component

this.props.children
looks the same as above.

children[0].props
looks like

classname:"home"
**pass: function Statement()**
title: "First title"


I want the
pass
property to look like. Above just prints out the Statement function.

$$typeof:Symbol(react.element)
_owner:ReactCompositeComponentWrapper
_self:null
_shadowChildren:undefined
_source:null
_store:
key:null
props:Object
__proto__:Object
**type: function Statement()**
ref:null


This is weird question, but long story I'm using a library and this is what it comes down to.

Answer

Using this.props.children is the idiomatic way to pass instantiated components to a react component

const Label = props => <span>{props.children}</span>
const Tab = props => <div>{props.children}</div>
const Page = () => <Tab><Label>Foo</Label></Tab>

When you pass a component as a parameter directly, you pass it uninstantiated and instantiate it by retrieving it from the props. This is an idiomatic way of passing down component classes which will then be instantiated by the components down the tree (e.g. if a component uses custom styles on a tag, but it wants to let the consumer choose whether that tag is a div or span):

const Label = props => <span>{props.children}</span>
const Button = props => {
    const Inner = props.inner;
    return <button><Inner>Foo</Inner></button>
}
const Page = () => <Button inner={Label}/>

If what you want to do is to pass a children-like parameter as a prop, you can do that:

const Label = props => <span>{props.content}</span>
const Tab = props => <div>{props.content}</div>
const Page = () => <Tab content={<Label content={Foo} />} />

After all, properties in React are just regular JavaScript object properties and can hold any value - be it a string, function or a complex object.

Comments