React: inline conditionally pass prop to component
JavascriptReactjsInlineJavascript Problem Overview
I would like to know if there is a better way to conditionally pass a prop than using an if-statement.
For example, right now I have:
var parent = React.createClass({
propTypes: {
editable: React.PropTypes.bool.isRequired,
editableOpts: React.PropTypes.shape({...})
},
render: function() {
if(this.props.editable) {
return (
<Child editable={this.props.editableOpts} />
);
} else {
// In this case, Child will use the editableOpts from its own getDefaultProps()
return (
<Child />
);
}
}
});
Is there a way to write this without the if-statement? I am was thinking something along the lines of a type of inline-if-statement in the JSX:
var parent = React.createClass({
propTypes: {
editable: React.PropTypes.bool.isRequired,
editableOpts: React.PropTypes.shape({...})
},
render: function() {
return (
<Child
{this.props.editable ? editable={this.props.editableOpts} : null}
/>
);
}
});
To wrap-up: I'm trying to find a way to define a prop for Child
, but pass a value (or do something else) such that Child
still pulls that prop's value from Child
's own getDefaultProps()
.
Javascript Solutions
Solution 1 - Javascript
You were close with your idea. It turns out that passing undefined
for a prop is the same as not including it at all, which will still trigger the default prop value. So you could do something like this:
var parent = React.createClass({
propTypes: {
editable: React.PropTypes.bool.isRequired,
editableOpts: React.PropTypes.shape({...})
},
render: function() {
return <Child
editable={this.props.editable ?
this.props.editableOpts :
undefined}
/>;
}
});
Solution 2 - Javascript
Add a spread operator to the this.props.editable
:
<Child {...(this.props.editable ? {editable: this.props.editableOpts} : {})} >
should work.
Solution 3 - Javascript
Define props
variable:
let props = {};
if (this.props.editable){
props.editable = this.props.editable;
}
And then use it in JSX:
<Child {...props} />
Here is a solution in your code:
var parent = React.createClass({
propTypes: {
editable: React.PropTypes.bool.isRequired,
editableOpts: React.PropTypes.shape({...})
},
render: function() {
let props = {};
if (this.props.editable){
props.editable = this.props.editable;
}
return (
<Child {...props} />
);
}
});
Source, React documentation: https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes
Solution 4 - Javascript
Actually, if your prop is boolean it isn't needed to implement condition but if you wanna add prop by inline condition you should write like below:
const { editable, editableOpts } = this.props;
return (
<Child {...(editable && { editable: editableOpts } )} />
);
Hope it doesn't confuse you. the {...
means it is spread operator like passing existed props: {...props}
and the editable &&
means if editable
is true
the { editable: editableOpts }
object will make and with {...
we will make a new object like it: {...{ editable: editableOpts }}
that it means editable={editableOpts}
but if this.porps.editable
is true.
Solution 5 - Javascript
also you can try this short hand way
<Child {...(this.props.editable && { editable: this.props.editableOpts })} />
Solution 6 - Javascript
var parent = React.createClass({
propTypes: {
editable: React.PropTypes.bool.isRequired,
editableOpts: React.PropTypes.shape({...})
},
render: function() {
return (
<Child
{...(this.props.editable && {editable=this.props.editableOpts})}
/>
);
}
});
This passes the props if they are defined. Else the props are not passed. In the other answer's the props are still passed but the value is undefined
which still means the props are being passed.
Solution 7 - Javascript
Hey I might be late to jump in but I want to share a small tip. In case you are here for the reason that you want to pass props dynamically. Then you can use * sign to import all the stuff as an alias , i.e in this case as grs then the imports will be in an object, then you can use that object to pass props dynamically. Hope this will help some of you.
import * as grs from "../components/Theme";
import React from "react";
const GridInput = ({ sp, ...props }) => {
return (
<Grid {...grs[`gr${sp}`]}>
<Input {...props} />
</Grid>
);
};
export default GridInput;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>