问题
I have a component <Button>
.
If the component doesn't has this.props.children
, I want to set the prop ariaLabel
as isRequired
, otherwise in can be optional. How do I do that?
ariaLabel
prop not required:
<Button>Add to bag</Button>
ariaLabel
prop has to be required:
<Button ariaLabel="Add to bag" icon={ favorite } />
if this.props.children
and this.props.ariaLabel
are empty, it throws an error saying that this.props.ariaLabel
is isRequired
<Button icon={ favorite } />
propTypes:
Button.propTypes = {
/** icon inside Button. */
icon: React.PropTypes.object,
/** Content inside button */
children: React.PropTypes.node,
/** Aria-label to screen readers */
ariaLabel: React.PropTypes.string, /*isRequired if children is empty */
};
Thanks
回答1:
You don't need another library, 'prop-types' provides this out of the box. See https://facebook.github.io/react/docs/typechecking-with-proptypes.html
Example:
import PropTypes from 'prop-types';
//.......
ExampleComponent.propTypes = {
showDelete: PropTypes.bool,
handleDelete: function(props, propName, componentName) {
if ((props['showDelete'] == true && (props[propName] == undefined || typeof(props[propName]) != 'function'))) {
return new Error('Please provide a handleDelete function!');
}
},
}
回答2:
This may be exactly what you need: https://github.com/thejameskyle/react-required-if
In your case, your propTypes would be:
import requiredIf from 'react-required-if';
Button.propTypes = {
/** icon inside Button. */
icon: React.PropTypes.object,
/** Content inside button */
children: React.PropTypes.node,
/** Aria-label to screen readers */
ariaLabel: requiredIf(React.PropTypes.string, props => !props.children), /*isRequired if children is empty */
};
回答3:
To add to @chickenchilli's answer above, you could abstract this into a more handy helper function like this:
conditionalPropType.js
export default function conditionalPropType(condition, message) {
if(typeof condition !== 'function') throw "Wrong argument type 'condition' supplied to 'conditionalPropType'";
return function(props, propName, componentName) {
if (condition(props, propName, componentName)) {
return new Error(`Invalid prop '${propName}' '${props[propName]}' supplied to '${componentName}'. ${message}`);
}
}
}
MyComponent.js
import PropTypes from 'prop-types';
import conditionalPropType from './conditionalPropType';
[...]
MyComponent.propTypes = {
conditionProp: PropTypes.bool,
dependentProp: conditionalPropType(props => (props.condition && typeof(props.someProp) !== 'boolean'), "'dependentProp' must be boolean if 'conditionProp' is true"),
};
回答4:
I think these solutions are a bit of an overkill partially because the question is requesting this.
I don't think you should complicate your code with this kind of situations you should aim to keep your code clean. You could do this on the render
rather than on propsTypes
...
render(){
if(!this.children || !this.ariaLabel) {
throw "You need children or ariaLabel";
return;
}
//rest of the code.
}
...
来源:https://stackoverflow.com/questions/42299335/react-props-set-isrequired-on-a-prop-if-another-prop-is-null-empty