Search code examples
reactjsreact-proptypes

Conditional React PropTypes


I have a React component which I would like to enforce one of two props to be provided - if neither is provided I'd like to be able to trigger a PropType warning:

MyComponent.propTypes = {
  firstProp: PropTypes.string.isRequired, // required only if `otherProp` not provided
  otherProp: PropTypes.string.isRequired, // required only if `firstProp` not provided
}

I believe this is possible with AirBnB's prop-types but I'm wondering if this can be done with only React PropTypes.


Solution

  • There is an npm for everything. Here is one for conditional prop types based on props. Here is an example of how I used it in a project for determining ad size prop types.

    import React, { Component } from 'react';
    import isRequiredIf from 'react-proptype-conditional-require';
    import PropTypes from 'prop-types';
    
    class AdSlot extends Component {
      // React component stuff
    }
    
    const slotPropTypes = PropTypes.oneOfType([
      PropTypes.string, // e.g. 'fluid'
      PropTypes.arrayOf(PropTypes.number), // e.g. [300, 250]
      PropTypes.arrayOf(PropTypes.array), // e.g. [[300, 250], [1650, 300]]
      PropTypes.arrayOf(PropTypes.oneOfType([ // e.g. ['fluid', [300, 250]]
        PropTypes.string.isRequired,
        PropTypes.array,
      ])),
    ]);
    
    const responsiveSizesPropTypes = PropTypes.arrayOf(PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.array,
      PropTypes.string,
    ]));
    
    const doesNotHaveResponsiveSizes = props => !(props.hasOwnProperty('responsiveSizes'));
    const doesNotHaveSlotSizes = props => !(props.hasOwnProperty('slotSizes'));
    
    AdSlot.proptypes = {
      slotSizes: isRequiredIf(slotPropTypes, doesNotHaveResponsiveSizes),
      responsiveSizes: isRequiredIf(responsiveSizesPropTypes, doesNotHaveSlotSizes),
    }
    
    export default AdSlot;