Reputation: 1513
I am trying to figure out the proper "react" way to pass in an optional prop that is an Element to a container component, that is handled differently from the children of that component.
For a simple example, I have a Panel component, which renders its children, that also has an optional "title" prop (which is an element rather than a string, for the sake of the example) that gets specially rendered (put in a special spot, with special behaviors in while maintaining the abstraction.
One option is to have a component which is pulled out of the children and rendered specially:
<Panel>
<Title> some stuff</Title>
<div> some other stuff</div>
</Panel>
But it seems wierd to have the children pulled out and handled separately like that.
How is this normally handled in react, and am I even thinking about this the right way
Upvotes: 18
Views: 55547
Reputation: 549
One thing you can do is have default props (usually initialised to a no-op) for your component.
For example, if you want to have an optional function prop:
class NewComponent extends React.Component {
...
componentDidMount() {
this.props.functionThatDoesSomething()
}
}
NewComponent.defaultProps = {
functionThatDoesSomething: () => {}
}
This way, parent components can choose to pass the function prop or not and your app won't crash due to the error
this.props.functionThatDoesSomething is not a function .
Upvotes: 0
Reputation: 79
When you need an attribute from your optional prop
, you will have to check first if the prop
was delivered. Otherwise, you will get a:
TypeError: Cannot read property 'yourPropProperty' of undefined
In conditional rendering context (depending on my optional this.props.ignore
array), this won't work:
{!this.props.ignore.includes('div')) && (
<div>
Hey
</div>
)}
Instead, you should do:
{(!this.props.ignore || !this.props.ignore.includes('div'))) && (
<div>
Hey
</div>
)}
Upvotes: 1
Reputation: 25842
you can do something like this
render(){
<div>
{this.props.title ? this.props.title : null}
{this.props.children}
</div>
}
basically if you pass a title element as a prop then create it as an element and render it. else just put in null...
to create it you would do something like this.
<Panel title={<Title>Something Here</Title>}
<div> something here</div>
</Panel>
This is generally how react should handle optional child components
Upvotes: 5
Reputation: 106027
You don't need to do anything special. Just pass the title component as a prop, and then use {this.props.title}
wherever you want it to be rendered:
class Panel extends React.Component {
render() {
return <div>
{this.props.title}
<div>Some other stuff...</div>
</div>;
}
}
class App extends React.Component {
render() {
var title = <Title>My Title</Title>;
return <Panel title={title}/>;
}
}
If you don't pass any value for the title
prop (or if the value is false
, null
, or undefined
) then nothing will be rendered there.
This is a fairly common pattern in React.
Upvotes: 18