Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define alternative required property in a React component PropTypes?

This is the use case: A component TableGroup should require a user to specify data property which is an array of objects to be rendered in the table or requestDataUrl property from where the component will get that array of objects. In short, one of these two properties is required but not both. How could I achieve that in the following component.propTypes object?

TableGroup.propTypes = {
  fieldNames: React.PropTypes.array.isRequired,
  dataFields: React.PropTypes.array.isRequired,
  uniqueField: React.PropTypes.string.isRequired,
  data: React.PropTypes.array,
  requestUrlSource: http://someurl/api/resource
}
like image 524
aquaman Avatar asked May 06 '17 06:05

aquaman


2 Answers

To achieve expected result, use below option

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
}
like image 51
Naga Sai A Avatar answered Sep 22 '22 07:09

Naga Sai A


According to React's doc, I think customProp should work perfectly for you.

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();  
}

after the declaration of your custom validation fn, now you could use it in

TableGroup.propTypes = {
  data: dataOrRequest,
  requestUrlSource: dataOrRequest
}
like image 45
fung Avatar answered Sep 24 '22 07:09

fung