Two sets of React propTypes

2.3k views Asked by At

I have a component that receives different props dynamically. How do I show this with propTypes? I was thinking something like this -

export default class Component extends React.Component {
  static propTypes = {
    propsOne: PropTypes.object,
  };
// OR
  static propTypes = {
    propsTwo: PropTypes.object,
  };
  // ...
}
3

There are 3 answers

0
Andy Ray On

You could use a custom validator, with one level of abstraction to specify the prop names

// Generate a custom React validation function
function eitherProp( prop1, prop2 ) {
    return ( props, propName, componentName ) => {
        const hasProp1 = typeof props[ prop1 ] === 'object';
        const hasProp2 = typeof props[ prop2 ] === 'object';

        // If both are provided, or neither, error
        if( ( hasProp1 && hasProp2 ) || !( hasProp1 || hasProp2 ) ) {
            return new Error( `Please provide either ${prop1} or ${prop2} of type object, not both` );
        }
    };
}

// Generate a reusable function for both props
const propsOneOrTwo = eitherProp( 'propsOne', 'propsTwo' );

static propTypes = {
    propsOne: propsOneOrTwo,
    propsTwo: propsOneOrTwo
};
1
AudioBubble On

You can use the existing React.PropTypes.oneOfType API to accomplish this. You would use it like:

static propTypes = {
    propOne: React.PropTypes.oneOfType([
        React.PropTypes.string,
        React.PropTypes.number
    ]),
    ...
};

However, if your type-checking requires logic, you might need to go with Andy's answer. But if your type-checking requires logic more complex than "this prop can be one of multiple types," it may be in your best interest to revisit the logic higher up the stack so that this is not required.

0
p8ul On

You can use oneOfType from react prop-types. React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library instead. https://reactjs.org/docs/typechecking-with-proptypes.html

import PropTypes from 'prop-types';

static propTypes = {
    propOne: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.number
    ]),
    ...
};