如何在React组件PropTypes中定义替代必需属性?

时间:2017-05-06 06:12:41

标签: reactjs react-proptypes

这是用例:组件TableGroup应该要求用户指定data属性,该属性是要在表 {{中呈现的对象数组1}}来自组件将获取该对象数组的属性。简而言之,这两个属性中的一个是必需的,但不是两个。我怎样才能在以下requestDataUrl对象中实现这一点?

component.propTypes

4 个答案:

答案 0 :(得分:4)

要达到预期效果,请使用以下选项

function dataOrRequest(props, propName, componentName) {
  return  (!props.hasOwnProperty('data') && 
             !props.hasOwnProperty('requestUrlSource')) 
            && new Error(`Either "data" or "requestUrlSource" is required`);
}


TableGroup.propTypes = {
  fieldNames: React.PropTypes.array.isRequired,
  dataFields: React.PropTypes.array.isRequired,
  uniqueField: React.PropTypes.string.isRequired,
  data: dataOrRequest,
  requestUrlSource: dataOrRequest
}

答案 1 :(得分:1)

根据React的doc,我认为customProp应该适合您。

dataOrRequest: function(props, propName, componentName) {
  function checkDataOrRequest() {
    return  (!props.hasOwnProperty('data')
      && !props.hasOwnProperty('requestUrlSource')) 
      && new Error(`Either "data" or "requestUrlSource" is required`);
  }

  function checkTypes() {
    if ((propName === 'data' && props.constructor !== Array) ||
        (propName === 'requestUrlSource' && props.constructor !== String)) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }

    return false;
  }

  return checkDataOrRequest() && checkTypes();  
}

宣布自定义验证fn后,现在可以在

中使用它
TableGroup.propTypes = {
  data: dataOrRequest,
  requestUrlSource: dataOrRequest
}

答案 2 :(得分:0)

我为此编写了一个NPM模块:https://www.npmjs.com/package/react-either-property

该代码维护类型检查选项,提供EitherOptional和EitherRequired策略-它支持在一个道具定义中组合多种用法。

请注意:自定义规则的属性名称是一次性的,其实际属性的使用尚不确定。

import { EitherOptional, EitherRequired } from 'react-either-property';

    [ module code goes here] 

ComponentSeven.propTypes = {
  east: PropTypes.number,
  west: PropTypes.number,
  north: PropTypes.number,
  south: PropTypes.number,
  ignored: EitherOptional('north', 'south'),
  undefined: EitherRequired('north', 'south'),
};

答案 3 :(得分:0)

使用isRequiredIf

@evcohen于4年前发布了一个PR,将isRequiredIf添加到了PropTypes库中。不幸的是,即使在那时,他们仍将PropTypes库置于维护模式,并且无法将其合并。

company I work for仍使用PropTypes,因此我们派生了PropTypes库的master分支,并在其中添加了此功能。

现在您可以执行以下操作:

data:             PropTypes.array.isRequiredIf( props => !props.requestUrlSource ),
requestUrlSource: PropTypes.string.isRequiredIf( props => !props.data )

超级干净,最小。

通过以下内容更新package.json,可以在自己的项目中随意使用our fork

"prop-types": "github:cntral/prop-types#isRequiredIf"

注意:它不需要布尔参数,只需要传递道具并需要返回布尔值的函数即可。