我有一个Card组件和一个CardGroup组件,当CardGroup有不是Card组件的孩子时,我想抛出一个错误。这是可能的,还是我试图解决错误的问题?
只允许react组件中特定类型的子项
IT技术
validation
reactjs
                    2021-04-20 02:17:15
                
                    
                
            
        6个回答
            对于 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
  }
}
您可以为每个孩子使用 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");
  }  
}
您可以使用自定义 propType 函数来验证子项,因为子项只是props。我还写了一篇关于这个的文章,如果你想要更多的细节。
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>
    );
  }
});
使用该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.");
    }
}
我建议使用Card.name代替'Card'string 来更好地维护和稳定uglify。
请参阅:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
对于那些使用 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;
        });
其它你可能感兴趣的问题