Reaccione la matriz de tipos con forma

244

¿Existe una forma integrada de usar los tipos de propiedad para garantizar que una matriz de objetos que se pasa a un componente sea en realidad una matriz de objetos de una forma específica?

Tal vez algo como esto?

annotationRanges: PropTypes.array(PropTypes.shape({
    start: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
})),

¿Me estoy perdiendo algo súper obvio aquí? Parece que esto sería muy buscado.

majorBummer
fuente

Respuestas:

370

Puede usarlo React.PropTypes.shape()como argumento para React.PropTypes.arrayOf():

// an array of a particular shape.
ReactComponent.propTypes = {
   arrayWithShape: React.PropTypes.arrayOf(React.PropTypes.shape({
     color: React.PropTypes.string.isRequired,
     fontSize: React.PropTypes.number.isRequired,
   })).isRequired,
}

Vea la sección de Validación de Prop de la documentación.

ACTUALIZAR

A partir de react v15.5, el uso React.PropTypesestá en desuso y el paquete independiente prop-typesdebe usarse en su lugar:

// an array of a particular shape.
import PropTypes from 'prop-types'; // ES6 
var PropTypes = require('prop-types'); // ES5 with npm
ReactComponent.propTypes = {
   arrayWithShape: PropTypes.arrayOf(PropTypes.shape({
     color: PropTypes.string.isRequired,
     fontSize: PropTypes.number.isRequired,
   })).isRequired,
}
Pierre Criulanscy
fuente
17
Vale la pena señalar el uso de .isRequireden cada propiedad de React.PropTypes.shape. Llegué aquí porque erróneamente por sentado que mediante el uso .isRequiredde React.PropTypes.arrayOf, yo no lo necesito en el interior. Para lograr la validación de cobertura completa, en realidad terminé aplicándolo directamente React.PropTypes.shapetambién.
gfullam
1
Sí, estaba haciendo exactamente lo mismo que usted, pero es mucho más poderoso tener la posibilidad de marcar solo según sea necesario las teclas que desea. Por cierto, lo explícito siempre es mejor que lo implícito para mí.
Pierre Criulanscy
Este ejemplo no falla la validación correctamente para mí. Si el if arrayWithShapees [] (una matriz vacía) No falla. si arrayWithShapees {} (un objeto) falla. Si arrayWithShape es [{dumb: 'something'}](una matriz sin los accesorios correctos) falla. Necesito que falle la validación si arrayWithShapees una matriz vacía. Solo quiero que pase si es una matriz no vacía con objetos que tienen accesorios colory fontsize. ¿Qué me estoy perdiendo?
sdc
50

Sí, debe usar en PropTypes.arrayOflugar de PropTypes.arrayen el código, puede hacer algo como esto:

import PropTypes from 'prop-types';

MyComponent.propTypes = {
  annotationRanges: PropTypes.arrayOf(
    PropTypes.shape({
      start: PropTypes.string.isRequired,
      end: PropTypes.number.isRequired
    }).isRequired
  ).isRequired
}

También para más detalles sobre los tipos de propiedad , visite Typechecking With PropTypes aquí

Alireza
fuente
3
¿Cuál es la razón para agregar .isRequired al objeto PropTypes.shape?
makovkastar
@makovkastar Porque sin ella, [undefined]pasaría la validación
user123
6

Hay una importación de taquigrafía ES6, puede hacer referencia. Más legible y fácil de escribir.

import React, { Component } from 'react';
import { arrayOf, shape, number } from 'prop-types';

class ExampleComponent extends Component {
  static propTypes = {
    annotationRanges: arrayOf(shape({
      start: number,
      end: number,
    })).isRequired,
  }

  static defaultProps = {
     annotationRanges: [],
  }
}
Moewiz
fuente
1
Por favor revise ¿Cómo escribo una buena respuesta ? Se desaconsejan las respuestas de solo código porque no explican cómo resuelven el problema en la pregunta. Debe actualizar su respuesta para explicar qué hace esto y cómo mejora las respuestas que esta pregunta ya tiene.
FluffyKitten
1

Si voy a definir los mismos tipos de props para una forma particular varias veces, me gusta resumirlo en un archivo de proptypes para que si la forma del objeto cambia, solo tengo que cambiar el código en un lugar. Ayuda a secar un poco la base de código.

Ejemplo:

// Inside my proptypes.js file
import PT from 'prop-types';

export const product = {
  id: PT.number.isRequired,
  title: PT.string.isRequired,
  sku: PT.string.isRequired,
  description: PT.string.isRequired,
};


// Inside my component file
import PT from 'prop-types';
import { product } from './proptypes;


List.propTypes = {
  productList: PT.arrayOf(product)
}
Yo Wakita
fuente
0

Esta fue mi solución para proteger contra una matriz vacía también:

import React, { Component } from 'react';
import { arrayOf, shape, string, number } from 'prop-types';

ReactComponent.propTypes = {
  arrayWithShape: (props, propName, componentName) => {
    const arrayWithShape = props[propName]
    PropTypes.checkPropTypes({ arrayWithShape:
        arrayOf(
          shape({
            color: string.isRequired,
            fontSize: number.isRequired,
          }).isRequired
      ).isRequired
    }, {arrayWithShape}, 'prop', componentName);
    if(arrayWithShape.length < 1){
      return new Error(`${propName} is empty`)
    }
  }
}
sdc
fuente