Реагуйте масив proptype з формою


245

Чи існує вбудований спосіб використання проптипів, щоб гарантувати, що масив об'єктів, що передаються компоненту, є насправді масивом об'єктів певної форми?

Може щось подібне?

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

Я пропускаю тут щось надто очевидне? Схоже, це було б дуже затребуваним.

Відповіді:


371

Ви можете використовувати React.PropTypes.shape()як аргумент для 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,
}

Див. Розділ « Підтвердження підтримки» документації.

ОНОВЛЕННЯ

Станом react v15.5, використовуючи React.PropTypesзасуджується і пакет автономний prop-typesповинен використовуватися замість:

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

17
Варто вказати на використання .isRequiredкожної властивості React.PropTypes.shape. Я приїхав сюди , бо я помилково припустив , що при використанні .isRequiredна React.PropTypes.arrayOf, мені не потрібно це всередині. Для досягнення повної перевірки покриття я фактично також застосував його безпосередньо React.PropTypes.shape.
gfullam

1
Так, я робив абсолютно те саме, що і ви, але набагато потужніше мати можливість позначити лише прапор, як вимагаються ключі, які ви хочете. Явне завжди краще, ніж неявне для мене, до речі.
П’єр Кріуланссі

Цей приклад не підходить для перевірки правильно для мене. Якщо if arrayWithShapeє [] (порожній масив), він не виходить з ладу. якщо arrayWithShapeє {} (об'єкт), він не вдається. Якщо arrayWithShape є [{dumb: 'something'}](масив без правильних реквізитів), він не вдається. Мені потрібно, щоб не вдалося перевірити, якщо arrayWithShapeце порожній масив. Я хочу, щоб він пройшов лише якщо це не порожній масив з об'єктами, які мають реквізити colorта fontsize. Що я пропускаю?
sdc

50

Так, вам потрібно використовувати PropTypes.arrayOfзамість PropTypes.arrayкоду, ви можете зробити щось подібне:

import PropTypes from 'prop-types';

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

Крім того, для отримання більш докладної інформації про proptypes , відвідування перевірки типів С PropTypes тут


3
У чому причина додавання .isRequred до об’єкту PropTypes.shape?
makovkastar

@makovkastar Тому що без цього [undefined]пройшов би перевірку
user123


6

Існує скорочення імпорту ES6, на яке ви можете посилатися. Більш легко читається та легко набирається.

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

1
Будь ласка, перегляньте Як написати гарну відповідь . Відповіді, що стосуються лише коду, відмовляються, оскільки вони не пояснюють, як вони вирішують питання у питанні. Вам слід оновити свою відповідь, щоб пояснити, що це робить, і як вона покращується в анонсованих відповідях, на які це питання вже є.
FluffyKitten

1

Якщо я повинен визначати одні й ті ж пропіотипи для певної форми кілька разів, мені подобається абстрагувати її файлом проптипів, так що якщо форма об'єкта зміниться, мені доведеться змінити код лише в одному місці. Це допомагає трохи висушити кодову базу.

Приклад:

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

Це було моє рішення також захистити від порожнього масиву:

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`)
    }
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.