big*_*ind 41 validation reactjs
我有一个Card
组件和一个CardGroup
组件,当CardGroup
有子Card
组件不是组件时,我想抛出一个错误.这是可能的,还是我试图解决错误的问题?
Die*_*o V 43
对于React 0.14+并使用ES6类,解决方案将如下所示:
class CardGroup extends Component {
render() {
return (
<div>{this.props.children}</div>
)
}
}
CardGroup.propTypes = {
children: function (props, propName, componentName) {
const prop = props[propName]
let error = null
React.Children.forEach(prop, function (child) {
if (child.type !== Card) {
error = new Error('`' + componentName + '` children should be of type `Card`.');
}
})
return error
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ark 19
您可以为每个子项使用displayName,通过以下类型访问:
for (child in this.props.children){
if (this.props.children[child].type.displayName != 'Card'){
console.log("Warning CardGroup has children that aren't Card components");
}
}
Run Code Online (Sandbox Code Playgroud)
mza*_*kie 14
您可以使用自定义propType函数来验证子项,因为子项只是道具.如果你想了解更多细节,我还写了一篇关于此的文章.
var CardGroup = React.createClass({
propTypes: {
children: function (props, propName, componentName) {
var error;
var prop = props[propName];
React.Children.forEach(prop, function (child) {
if (child.type.displayName !== 'Card') {
error = new Error(
'`' + componentName + '` only accepts children of type `Card`.'
);
}
});
return error;
}
},
render: function () {
return (
<div>{this.props.children}</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
对于那些使用 TypeScript 版本的人。您可以像这样过滤/修改组件:
this.modifiedChildren = React.Children.map(children, child => {
if (React.isValidElement(child) && (child as React.ReactElement<any>).type === Card) {
let modifiedChild = child as React.ReactElement<any>;
// Modifying here
return modifiedChild;
}
// Returning other components / string.
// Delete next line in case you dont need them.
return child;
});
Run Code Online (Sandbox Code Playgroud)
使用该React.Children.forEach
方法迭代子项并使用该name
属性检查类型:
React.Children.forEach(this.props.children, (child) => {
if (child.type.name !== Card.name) {
console.error("Only card components allowed as children.");
}
}
Run Code Online (Sandbox Code Playgroud)
我建议使用Card.name
代替'Card'
string 来更好地维护和稳定uglify。
请参阅:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
小智 6
如果使用 Typescript,则必须将“React.isValidElement(child)”与“child.type”一起使用,以避免类型不匹配错误。
React.Children.forEach(props.children, (child, index) => {
if (React.isValidElement(child) && child.type !== Card) {
error = new Error(
'`' + componentName + '` only accepts children of type `Card`.'
);
}
});
Run Code Online (Sandbox Code Playgroud)
您可以向组件添加一个 prop Card
,然后在组件中检查此 prop CardGroup
。这是在 React 中实现此目的最安全的方法。
该 prop 可以添加为 defaultProp,因此它始终存在。
class Card extends Component {
static defaultProps = {
isCard: true,
}
render() {
return (
<div>A Card</div>
)
}
}
class CardGroup extends Component {
render() {
for (child in this.props.children) {
if (!this.props.children[child].props.isCard){
console.error("Warning CardGroup has a child which isn't a Card component");
}
}
return (
<div>{this.props.children}</div>
)
}
}
Run Code Online (Sandbox Code Playgroud)
检查 Card 组件是否确实是 Card 组件,type
或者displayName
不安全,因为它在生产使用期间可能无法工作,如下所示:https ://github.com/facebook/react/issues/6167#issuecomment-191243709