Реагуйте масив 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.