Phản ứng mảng proptype với hình dạng


244

Có cách tích hợp nào để sử dụng proptype để đảm bảo rằng một mảng các đối tượng được truyền cho một thành phần thực sự là một mảng các đối tượng có hình dạng cụ thể không?

Có lẽ một cái gì đó như thế này?

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

Tôi có thiếu một cái gì đó siêu rõ ràng ở đây? Có vẻ như điều này sẽ được tìm kiếm cao.

Câu trả lời:


370

Bạn có thể sử dụng React.PropTypes.shape()làm đối số để 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,
}

Xem phần Xác thực Prop của tài liệu.

CẬP NHẬT

Kể từ đó react v15.5, việc sử dụng React.PropTypesbị phản đối và gói độc lập prop-typesnên được sử dụng thay thế:

// 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
Đó là giá trị chỉ ra việc sử dụng .isRequiredtrên mỗi tài sản của React.PropTypes.shape. Tôi đến đây vì tôi sai cho rằng bằng cách sử dụng .isRequiredtrên React.PropTypes.arrayOf, tôi không cần nó bên trong. Để đạt được xác nhận bảo hiểm đầy đủ, tôi thực sự đã kết thúc việc áp dụng nó trực tiếp React.PropTypes.shape.
gfullam

1
Vâng, tôi đã làm điều tương tự chính xác so với bạn, nhưng sẽ mạnh mẽ hơn khi có khả năng chỉ gắn cờ theo yêu cầu các phím bạn muốn. Bằng cách này, luôn luôn tốt hơn là ngầm cho tôi.
Pierre Criulanscy

Ví dụ này không xác nhận chính xác cho tôi. Nếu if arrayWithShapelà [] (một mảng trống) Nó không thất bại. if arrayWithShapelà {} (một đối tượng) thì không thành công. Nếu arrayWithShape[{dumb: 'something'}](một mảng không có đạo cụ chính xác) thì thất bại. Tôi cần nó để xác nhận thất bại nếu arrayWithShapelà một mảng trống. Tôi chỉ muốn nó vượt qua nếu nó là một mảng không trống với các đối tượng có đạo cụ colorfontsize. Tôi đang thiếu gì?
sdc

50

Có, bạn cần sử dụng PropTypes.arrayOfthay vì PropTypes.arraytrong mã, bạn có thể làm một cái gì đó như thế này:

import PropTypes from 'prop-types';

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

Ngoài ra để biết thêm chi tiết về proptypes , hãy truy cập typechecking With PropTypes tại đây


3
Lý do để thêm .isRequired vào đối tượng PropTypes.shape là gì?
makovkastar

@makovkastar Bởi vì không có nó, [undefined]sẽ vượt qua xác nhận
user123


6

Có nhập khẩu tốc ký ES6, bạn có thể tham khảo. Dễ đọc hơn và dễ gõ.

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
Vui lòng xem lại Làm thế nào để tôi viết một câu trả lời tốt . Các câu trả lời chỉ có mã không được khuyến khích vì chúng không giải thích cách chúng giải quyết vấn đề trong câu hỏi. Bạn nên cập nhật câu trả lời của mình để giải thích điều này và cách cải thiện câu trả lời được nêu lên mà câu hỏi này đã có.
FluffyKitten

1

Nếu tôi định nghĩa các proptype giống nhau cho một hình dạng cụ thể nhiều lần, tôi thích trừu tượng hóa nó thành một tệp proptypes để nếu hình dạng của đối tượng thay đổi, tôi chỉ phải thay đổi mã ở một nơi. Nó giúp làm khô codebase một chút.

Thí dụ:

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

0

Đây cũng là giải pháp của tôi để bảo vệ chống lại một mảng trống:

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`)
    }
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.