访问React组件中嵌套propTypes中的所有prop



我正试图根据disableLightbox的属性有条件地使lightboxImage成为必需或不必需。然而,当我从lightboxImage中读取道具时,我只得到了第一级属性(src、width、height、aspectRatio),而没有得到更高级别的属性(photos、disableLightbox)。有什么方法可以让我阅读所有的属性吗?

Gallery.propTypes = {
    photos: React.PropTypes.arrayOf(
        React.PropTypes.shape({
            src: React.PropTypes.string.isRequired, 
            width: React.PropTypes.number.isRequired,
            height: React.PropTypes.number.isRequired,
            aspectRatio: React.PropTypes.number.isRequired,
            lightboxImage: props => console.log(props)
        })  
    ).isRequired,
    disableLightbox: React.PropTypes.bool
};     

@MatthewHerbst解释了自定义验证器的关键思想,但这里有一个更完整、更适用、更简单的示例代码重写版本(仅供参考,未经测试):

photos: function (props, propName, componentName) {
  // I don't know what `lightboxImage` is, I'll assume string.
  var lightboxImageValidator = React.PropTypes.string;
  if (!props.disableLightbox) {
    lightboxImageValidator = lightboxImageValidator.isRequired;
  }
  return React.PropTypes.arrayOf(
    React.PropTypes.shape({
      src: React.PropTypes.string.isRequired, 
      width: React.PropTypes.number.isRequired,
      height: React.PropTypes.number.isRequired,
      aspectRatio: React.PropTypes.number.isRequired,
      lightboxImage: lightboxImageValidator,
    })  
  ).isRequired.apply(this, arguments);
}

虽然使用标准PropType验证器是不可能的,但可以通过为disableLightboxphotos编写自定义验证器来实现这一点。让我们使用disableLightbox来做这件事,因为这就是你所问的:

disableLightbox: function(props, propName, componentName) {
  // First, we need to check that we're a Boolean
  // You could do this with PropTypes.boolean but it's much simpler to do it yourself
  let type = typeof props[propName];
  if (type !== 'boolean') {
    return new Error(propName + ' supplied to ' + componentName + ' is of type `' + type +'`. `boolean` expected. Validation failed.');
  }
  if (props[propName]) {
    if (props.hasOwnProperty('photos') {
      // Now we do the fun part. Here we are manually checking the validation of photos
      // using the built-in PropTypes, but this time with lightboxImage required
      let typeChecker = PropTypes.arrayOf(PropTypes.shape({
        lightboxImage.string.isRequired
      }));
      return typeChecker(props, 'photos', componentName, 'prop');
    } else {
      // Missing the photos prop
      return new Error(propName + ' supplied to ' + componentName + ' has a true value, but prop `photos` is missing. Validation failed.');
    }
  } else {
    // disableLightbox is false, so no need to check lightboxImage
  }
}

我强烈建议仔细阅读文档中的自定义验证器示例(免责声明:我编写了customArrayProp示例)。上面的例子可能被认为有点粗糙,但它应该有效。您还应该注意,如果photos很大,那么上面的内容可能会对性能产生影响,因为它基本上是在重新运行验证。

最新更新