0
votes

I established my PropTypes on App component for all props that are being passed to children.

class App extends Component {
    constructor( props ) {
        super( props );

        this.state = {
            anyProps : undefined',
        };
    }

    propsValues = {
        anyProp: [ 'undefined', 'neutral', 'evil', 'good' ],
    };

   (...)

I can receive PropTypes on child stateless components, and use its value to validate other props, like this:

const SFComponent = ({
    anyProp,
    propsValues,
}) => {

    SFComponent.propTypes = {
        anyProp : PropTypes.oneOf( propsValues.anyProp ).isRequired,
        propsValues : PropTypes.objectOf( PropTypes.arrayOf( PropTypes.string )),
    }; 

    (...)

But when I try to do the same with a child stateful component it just doesn't work. I can't use the same sintaxis and props are still not received when valitdating types.

class StatefulComponent extends React.Component {

    constructor( props ) {
        super( props );
        this.state = {
            anyAttribute : true,
            anotherAttribute : null,
        };
    }

    static propTypes = {
        anyProp : PropTypes.oneOf( this.props.propsValues.anyProp ).isRequired,
        propsValues : PropTypes.objectOf( PropTypes.arrayOf( PropTypes.string )),

    (...)

The above snippet throws an error stating this is undefined. I've also tried other possibilities but none works.

So, any ideas on how can I achieve the same result that I achieve in stateless components, being able to use props.propsValues as a base validator for all my props on child stateful components? Thanks!

1

1 Answers

0
votes

this.props don't exist at the moment when propTypes is used because propTypes is static.

SFComponent is a hack that won't work as intended because SFComponent.propTypes affects only component next render. This should be done with HOC:

const withAnyProp = Comp => ({ anyProp, ...props }) =>
  const Wrapper = (...props) => <Comp {...props} />;
  Wrapper.propTypes = {
    anyProp : PropTypes.oneOf(anyProp).isRequired,
  };
  return <Wrapper {...props} />;
};
const SFComponentWithAnyProp = withAnyProp(SFComponent);

Orop types are just built-in replacement for static type checks. TypeScript or Flow types should preferably be used instead.

In case it's needed to use dynamic type checks, props can be asserted directly, in functional component body or class component hook methods.