Pass react component as props
Solution 1
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; // Note: variable name _must_ start with a capital letter
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.
Solution 2
As noted in the accepted answer - you can use the special { props.children } property. However - you can just pass a component as a prop as the title requests. I think this is cleaner sometimes as you might want to pass several components and have them render in different places. Here's the react docs with an example of how to do it:
https://reactjs.org/docs/composition-vs-inheritance.html
Make sure you are actually passing a component and not an object (this tripped me up initially).
The code is simply this:
const Parent = () => {
return (
<Child componentToPassDown={<SomeComp />} />
)
}
const Child = ({ componentToPassDown }) => {
return (
<>
{componentToPassDown}
</>
)
}
Solution 3
By using render prop you can pass a function as a component and also share props from parent itself:
<Parent
childComponent={(data) => <Child data={data} />}
/>
const Parent = (props) => {
const [state, setState] = useState("Parent to child")
return <div>{props.childComponent(state)}</div>
}
Solution 4
I had to render components conditionally, so the following helped me:
const Parent = () => {
return (
<Child componentToPassDown={<SomeComp />} />
)
}
const Child = ({ componentToPassDown }) => {
return (
<>
{conditionToCheck ? componentToPassDown : <div>Some other code</div>}
</>
)
}
Solution 5
In my case, I stacked some components (type_of_FunctionComponent) into an object like :
[
{...,one : ComponentOne},
{...,two : ComponentTwo}
]
then I passed it into an Animated Slider, and in the the slide Component, I did:
const PassedComponent:FunctionComponent<any> = Passed;
then use it:
<PassedComponent {...custom_props} />
chefcurry7
Updated on July 08, 2022Comments
-
chefcurry7 11 months
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" title="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 likeclassname:"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 a weird question, but long story I'm using a library and this is what it comes down to.
-
Aatif Bandey over 6 yearswhy do you want to pass component as props ? when you can import
-
ivarni over 6 years@AatifBandey Because he's passing different components? How would you solve this using imports exactly? Passing strings and doing equality checks? That makes no sense.
-
Michael Freidgeim about 3 yearsDoes this answer your question? How to pass in a react component into another react component to transclude the first component's content?
-
-
Norfeldt about 6 yearsI know you came with a lot of good arrow function examples. But would you mind showing how the code would look like if it was separated into different files? I'm a bit confused about how to use the
class
andexport
-
Stefan Dragnev about 6 yearsJust use
export const Foo = ...
and then elsewhereimport {Foo} from "./foo"
-
igo almost 6 yearsHint: make sure that
Inner
is notinner
. Otherwise doesn't work -
NicoleZ over 2 yearsif child has a prop.how do I access that in the parent.
-
Wide Awake over 2 years@NicoleZ - the basic idea is to turn the question around. Ie, create the variable in the parent and pass it down to the child as a prop. If you want the child to change the variable then you need to create a function to do this in the parent and also pass that down as another prop.
-
totymedli over 2 yearsBasically to pass a component like
<Com a="5" />
just turn it into an arrow function:() => <Com a="5" />
-
Hadi Pawar about 2 yearsHow can i give props to
componentToPassDown
in the chidl method? -
duhaime about 2 years@HadiPawar just pass the props down:
<Child componentToPassDown={<SomeComp yeet={true} />} />
-
Cat Perry 12 monthsUsing and iteration of React.createElement worked for me