web-dev-qa-db-fra.com

React proptype array avec la forme

Existe-t-il un moyen intégré d’utiliser des types de propriétés pour s’assurer qu’un tableau d’objets transmis à un composant est en réalité un tableau d’objets d’une forme spécifique?

Peut-être quelque chose comme ça?

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

Est-ce que je manque quelque chose de très évident ici? On dirait que cela serait très recherché.

184
majorBummer

Vous pouvez utiliser React.PropTypes.shape() comme argument de 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,
}

Voir la section Prop Validation de la documentation.

METTRE À JOUR

À partir de react v15.5, utiliser React.PropTypes est obsolète et le paquet autonome prop-types devrait être utilisé à la place:

// 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,
}
276
Pierre Criulanscy

Oui, vous devez utiliser PropTypes.arrayOf au lieu de PropTypes.array dans le code, vous pouvez faire quelque chose comme ceci:

import PropTypes from 'prop-types';

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

Aussi pour plus de détails sur proptypes, visitez Typechecking With PropTypesici

39
Alireza

Et la voilà ... juste sous mon nez:

À partir des documents de réaction eux-mêmes: https://facebook.github.io/react/docs/reusable-components.html

// An array of a certain type
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
22
majorBummer

Vous pouvez faire référence à une importation abrégée ES6. Plus lisible et facile à taper.

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: [],
  }
}
4
Moewiz

Si je dois définir plusieurs fois les mêmes types de propriétés pour une forme particulière, j'aime bien les résumer dans un fichier de types de propriétés de sorte que si la forme de l'objet change, je ne dois changer le code qu'à un seul endroit. Cela aide à assécher un peu la base de code.

Exemple:

// 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)
}
1
Yo Wakita

C'était ma solution pour me protéger aussi contre un tableau vide:

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`)
    }
  }
}
0
sdc