validate validaciones react library form empty bootstrap validation reactjs

validation - validaciones - solo permite que los niños de un tipo específico reaccionen



required react (7)

Tengo un componente de Card y un componente de CardGroup , y me gustaría lanzar un error cuando CardGroup tiene hijos que no son componentes de la Card . ¿Es esto posible, o estoy tratando de resolver el problema equivocado?


Para React 0.14+ y el uso de clases ES6, la solución se verá así:

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 } }


Puede usar la displayName para cada niño, accediendo por tipo:

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"); } }


Hice un PropType personalizado para esto que llamo equalTo . Puedes usarlo así ...

class MyChildComponent extends React.Component { ... } class MyParentComponent extends React.Component { static propTypes = { children: PropTypes.arrayOf(PropTypes.equalTo(MyChildComponent)) } }

Ahora, MyParentComponent solo acepta hijos que son MyChildComponent . Puede verificar elementos html como este ...

PropTypes.equalTo(''h1'') PropTypes.equalTo(''div'') PropTypes.equalTo(''img'') ...

Aquí está la implementación ...

React.PropTypes.equalTo = function (component) { return function validate(propValue, key, componentName, location, propFullName) { const prop = propValue[key] if (prop.type !== component) { return new Error( ''Invalid prop `'' + propFullName + ''` supplied to'' + '' `'' + componentName + ''`. Validation failed.'' ); } }; }

Podría extender esto fácilmente para aceptar uno de muchos tipos posibles. Tal vez algo como ...

React.PropTypes.equalToOneOf = function (arrayOfAcceptedComponents) { ... }


Publiqué el paquete que permite validar los tipos de elementos React https://www.npmjs.com/package/react-element-proptypes :

const ElementPropTypes = require(''react-element-proptypes''); const Modal = ({ header, items }) => ( <div> <div>{header}</div> <div>{items}</div> </div> ); Modal.propTypes = { header: ElementPropTypes.elementOfType(Header).isRequired, items: React.PropTypes.arrayOf(ElementPropTypes.elementOfType(Item)) }; // render Modal React.render( <Modal header={<Header title="This is modal" />} items={[ <Item/>, <Item/>, <Item/> ]} />, rootElement );


static propTypes = { children : (props, propName, componentName) => { const prop = props[propName]; return React.Children .toArray(prop) .find(child => child.type !== Card) && new Error(`${componentName} only accepts "<Card />" elements`); }, }


Puede agregar un apuntalante a su componente de Card y luego buscar este accesorio en su componente CardGroup . Esta es la forma más segura de lograr esto en React.

Este accesorio se puede agregar como un valor predeterminado por lo que siempre está ahí.

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> ) } }

Comprobar si el componente de la Tarjeta es efectivamente un componente de la Tarjeta utilizando el type y displayName no es seguro, ya que puede no funcionar durante el uso de la producción como se indica aquí: https://github.com/facebook/react/issues/6167#issuecomment-191243709


Puede usar una función propType personalizada para validar a los niños, ya que los niños son sólo accesorios. También escribí un artículo sobre esto, si quieres más detalles.

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> ); } });