React PropTypes:要求数组至少有一个元素

6

我在我的React应用程序中使用prop-types库,遇到以下情况:

MyComponent.propTypes = {
  foo: PropTypes.arrayOf(
    PropTypes.shape({
      bar: PropTypes.string.isRequired,
      baz: PropTypes.number.isRequired,
    })
  ).isRequired
}

通过在 foo 上设置 isRequiredfoo 必须是一个数组(不是 null/undefined)。但是,它仍然允许是一个空数组。在我的情况下,我想要求该数组至少包含一个元素。 可以通过自定义验证函数实现此目的:
MyComponent.propTypes = {
  foo: function (props, propName, componentName) {
    const val = props[propName]
    if (!Array.isArray(val)) return new Error(`${propName} must be an array`)
    if (val.length === 0) return new Error(`${propName} must have at least one element`)

    val.forEach(function (elem) {
      if (typeof elem.bar !== 'string') return new Error(`${propName}.bar must be a string`)
      if (typeof elem.baz !== 'number') return new Error(`${propName}.baz must be a number`)
    })
  }
}

然而,这种方法并不美观,感觉如果数组包含更大或更复杂的对象,它可能会很快变得更加复杂。

有没有更简洁的方法可以实现这个功能?


1
我认为你所做的很好。 - Tomasz Mularczyk
2个回答

3

您可以使用PropTypes.checkPropTypes函数 - 您仍需要验证器函数,但数组内部的对象可以通过PropTypes进行描述:

const myPropShape = {
  bar: PropTypes.string.isRequired,
  baz: PropTypes.number.isRequired,
}

MyComponent.propTypes = {
  foo: function (props, propName, componentName) {
    const val = props[propName]
    if (!Array.isArray(val)) return new Error(`${propName} must be an array`)
    if (val.length === 0) return new Error(`${propName} must have at least one element`)

    val.forEach(elem =>
      PropTypes.checkPropTypes(
        myPropShape,
        elem,
        'prop',
        `${componentName}.${propName}`,
      ),
    )
  }
}


1

您的帖子提出了两个问题:

  1. 有没有更简洁的方法来验证一个属性是否至少包含一个元素?
  2. 如何验证数组中对象的属性?

1:为数组创建一个简单的验证器,并像通常一样在propTypes中应用它

在组件中创建验证器

const arrayNonEmpty = (props, propName) => {
  const myProp = props[propName];
  if (!Array.isArray(myProp)) return new Error(`${propName} must be an array.`);
  if (myProp.length < 1) return new Error(`${propName} must have at least one element.`);
};

检查属性foo是否是至少有一个元素的数组

// Use the validator as normal
MyComponent.propTypes = {
  foo: arrayNonEmpty,
};

这是最简单、干净的方法。你的代码非常接近,但有一些额外的行在验证数组中对象的属性;根据以下原因,这段代码是不需要的。
2:验证数组内部的对象
我建议在子组件中验证数组内对象的属性。
如果您传递一个对象数组,您可能会在视图中表示这些对象。只需添加一个表示数组元素的子组件,并验证传递给子组件的对象的propTypes。
另一个选项是将数组的第一个对象与其余部分分开传递。然后,它可以像任何其他prop一样正常验证。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接