React.PropTypes array with specific length

后端 未结 4 1511
一向
一向 2021-02-19 22:05

Is it possible to use React.PropTypes to enforce length\'s on an array?

Here is a very simple case:

const TWO_NUMBERS = PropTypes.array; // i          


        
相关标签:
4条回答
  • 2021-02-19 22:50

    in this case you would need to write your own special PropTypes function which react provides you to do.

    const TWO_NUMBERS = function(props, propName, componentName) {
      if (!Array.isArray(props.TWO_NUMBERS) || props.TWO_NUMBERS.length != 2 || !props.TWO_NUMBERS.every(Number.isInteger)) {
        return new Error(`${propName} needs to be an array of two numbers`);
      }
    
      return null
    }
    

    This would throw an error if TWO_NUMBERS isn't an array, isn't an array of two, and isn't an array of only integers.

    you can get information about proptype functions here:

    https://facebook.github.io/react/docs/typechecking-with-proptypes.html#react.proptypes

    its at the bottom of that example block.

    0 讨论(0)
  • 2021-02-19 22:51

    A custom function would be the correct approach here.

      const propTypes = {
        TWO_NUMBERS: arrayOfLength.bind(null, 2)
      }
    
      const arrayOfLength = (expectedLength, props, propName, componentName) => {
        const arrayPropLength = props[propName].length
    
        if (arrayPropLength !== expectedLength) {
          return new Error(
            `Invalid array length ${arrayPropLength} (expected ${expectedLength}) for prop ${propName} supplied to ${componentName}. Validation failed.`
          )
        }
      }
    
    0 讨论(0)
  • 2021-02-19 22:56

    Inspired by the answer of @finalfreq, I came up with this. It handles two numbers (floats in this case) and can also be used as arrayOf(twoNumbers). Not sure how to make it work like twoNumbers.isRequired yet...

    Also I think the code is cleaner and easier to follow if you don't use the negation in the validation comparison.

    import invariant from 'invariant';
    
    function isValid(value) {
      return Array.isArray(value) && value.length === 2 && value.every(Number.isFinite);
    }
    
    export default function twoNumbers(props, propName, componentName) {
      if (Array.isArray(props)) {
        props.forEach((item, index) => {
          invariant(
            isValid(item),
            `Array item index ${index} is ${item}, but needs to be an array of two numbers`
          );
        });
      }
    
      const value = props[propName];
    
      if (!value) return; // not required so could be null
    
      invariant(isValid(value), `${componentName} ${propName} needs to be an array of two numbers`);
    }
    
    0 讨论(0)
  • 2021-02-19 23:02

    PropTypes checks for types not for attributes. Also, checking for PropTypes is disabled in production mode. That makes it impossible for PropTypes to check for ever changing array lengths during run-time.

    0 讨论(0)
提交回复
热议问题