我有一个组件<Button>
如果组件没有this.props.children
,我想将道具ariaLabel
设置为isRequired
,否则可以是可选的。我该怎么做?
ariaLabel
道具不需要:
<Button>Add to bag</Button>
必须要求 ariaLabel
道具
<Button ariaLabel="Add to bag" icon={ favorite } />
如果this.props.children
和this.props.ariaLabel
为空,则会发出错误消息,指出this.props.ariaLabel
为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 */
};
由于
答案 0 :(得分:79)
你不需要另一个图书馆,&#39; prop-types&#39;开箱即用。 见https://facebook.github.io/react/docs/typechecking-with-proptypes.html
示例:
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!';
);
}
},
}
答案 1 :(得分:14)
这可能正是您所需要的:https://github.com/thejameskyle/react-required-if
在您的情况下,您的propTypes将是:
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 */
};
答案 2 :(得分:4)
要添加到上述@chickenchilli的答案中,您可以将其抽象为更方便的辅助函数,如下所示:
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}`);
}
}
}
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"),
};
答案 3 :(得分:1)
isRequiredIf
。 4年前有一个PR,它向PropTypes库中添加了isRequiredIf
。不幸的是,即使在那时,他们仍将PropTypes库置于维护模式,并且无法将其合并。
company I work for仍使用PropTypes,因此我们派生了PropTypes库的master
分支,并在其中添加了此功能。
现在您可以执行以下操作:
ariaLabel: PropTypes.string.isRequiredIf( props => props.children )
超级干净,最小。
通过以下内容更新package.json
,可以在自己的项目中随意使用our fork:
"prop-types": "github:cntral/prop-types#isRequiredIf"
注意:它不需要布尔参数,只需要传递道具并需要返回布尔值的函数即可。
答案 4 :(得分:0)
我认为这些解决方案有些过头了,因为这个问题正在要求这样做。
我不认为您应该使代码复杂化,而应该保持代码干净。您可以在render
而不是propsTypes
...
render(){
if(!this.children || !this.ariaLabel) {
throw "You need children or ariaLabel";
return;
}
//rest of the code.
}
...