React proptype array with shape

前端 未结 6 1085
感情败类
感情败类 2020-12-12 15:11

Is there a built-in way to use proptypes to ensure that an array of objects being passed to a component is actually an array of objects of a specific shape?

Maybe so

相关标签:
6条回答
  • 2020-12-12 15:44

    This was my solution to protect against an empty array as well:

    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 讨论(0)
  • 2020-12-12 15:47

    There's a ES6 shorthand import, you can reference. More readable and easy to type.

    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: [],
      }
    }
    
    0 讨论(0)
  • 2020-12-12 15:49

    And there it is... right under my nose:

    From the react docs themselves: https://facebook.github.io/react/docs/reusable-components.html

    // An array of a certain type
        optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
    
    0 讨论(0)
  • 2020-12-12 15:59

    Yes, you need to use PropTypes.arrayOf instead of PropTypes.array in the code, you can do something like this:

    import PropTypes from 'prop-types';
    
    MyComponent.propTypes = {
      annotationRanges: PropTypes.arrayOf(
        PropTypes.shape({
          start: PropTypes.string.isRequired,
          end: PropTypes.number.isRequired
        }).isRequired
      ).isRequired
    }
    

    Also for more details about proptypes, visit Typechecking With PropTypes here

    0 讨论(0)
  • 2020-12-12 15:59

    If I am to define the same proptypes for a particular shape multiple times, I like abstract it out to a proptypes file so that if the shape of the object changes, I only have to change the code in one place. It helps dry up the codebase a bit.

    Example:

    // 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 讨论(0)
  • 2020-12-12 16:08

    You can use React.PropTypes.shape() as an argument to 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,
    }
    

    See the Prop Validation section of the documentation.

    UPDATE

    As of react v15.5, using React.PropTypes is deprecated and the standalone package prop-types should be used instead :

    // 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,
    }
    
    0 讨论(0)
提交回复
热议问题