web-dev-qa-db-ja.com

特定の長さのReact.PropTypes配列

Rect.PropTypesを使用して配列に長さを強制することは可能ですか?

これは非常に単純なケースです:

const TWO_NUMBERS = PropTypes.array; // i need this to be an array of two numbers

私はJavaScriptの配列が単なるオブジェクトであることを知っているので、私はこれを試しました:

const TWO_NUMBERS = PropTypes.shape({
    0: PropTypes.number.isRequired,
    1: PropTypes.number.isRequired,
});

しかし、これは私に警告を伝え続けますexpected an object but got an array

10
Noitidart

この場合、reactが提供する独自のPropTypes関数を作成する必要があります。

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
}

TWO_NUMBERSが配列ではなく、2の配列でもなく、整数のみの配列でもない場合、これはエラーをスローします。

ここでproptype関数に関する情報を取得できます。

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

そのサンプルブロックの下部にあります。

11
finalfreq

ここでは、カスタム関数が正しいアプローチになります。

  const propTypes = {
    TWO_NUMBERS: arrayOfLength.bind(null, 1),
  }

  const arrayOfLength = function(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.`
      );
    }
  },
4
garrettmaring

@finalfreqの答えに触発されて、私はこれを思いつきました。 2つの数値(この場合は浮動小数点数)を処理し、arrayOf(twoNumbers)としても使用できます。 twoNumbers.isRequiredのように機能させる方法はまだわかりません...

また、検証の比較で否定を使用しない場合は、コードがより簡潔でわかりやすいと思います。

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`);
}
1