简体   繁体   中英

react extract proptypes, isRequired and defaultProps from component

I have the following component:

import React from 'react'
import PropTypes from 'prop-types'

const MyComponent = ({ text1, text2 }) => {
    return (
        <div>
            <p>{text1}</p>
            <p>{text2}</p>
        </div>
    )
}
MyComponent.propTypes = {
    text1: PropTypes.string,
    text2: PropTypes.string,
}
MyComponent.defaultPropTypes = {
    text1: 'React',
    text2: 'is cool',
}

export default MyComponent

and then I am importing it like this

import MyComponent from "./MyComponent";

console.log(MyComponent.propTypes)

This prints a object with all propNames as a function. I am not able to get the type from the object. How do I get the proptype (in this example string) and "isRequired" from this component? I want to use it for automatically render a table with all possible propNames + PropType + isRequired + defaultPropType

You cant retrieve the information you are looking for by reading the propType properties. Each item in the propTypes is actually a validation wrapper function that obscures the actual type validation.

There is a way to achieve what you are looking for, but it isn't particularly pretty. See this answer .

Another option for your scenario is to create and export another static property with your component that includes the information you need. Then create a utility method to map your property data into PropTypes

For example:

// -- utility

const validators = {
    string: PropTypes.string,
    string_required: PropTypes.string.isRequired,
}

const getPropTypesFromValidators = (o) => {
    return Object.entries(MyComponent.validators).reduce((acc, [field, validatorKey]) => {
        return { ...acc, [field]: validators[validatorKey] }
    }, {})
}


/// --- component

const MyComponent = ({ text1, text2 }) => {
    return (
        <div>
            <p>{text1}</p>
            <p>{text2}</p>
        </div>
    )
}
MyComponent.validators = {
    text1: 'string',
    text2: 'string_required',
}

MyComponent.propTypes = getPropTypesFromValidators(MyComponent.validators);

MyComponent.defaultPropTypes = {
    text1: 'React',
    text2: 'is cool',
}

// -- app

console.log(MyComponent.validators);

A second option could be to wrap the PropTypes object and add your own annotations, for example:


const AnnotatedPropTypes = Object.keys(PropTypes).reduce((acc, key) => {
  const fn = (...args) => PropTypes[key](...args);
  fn.description = key;

  if (typeof PropTypes[key].isRequired === "function") {
    fn.isRequired = (...args) => PropTypes[key].isRequired(...args);
    fn.isRequired.description = `${key} (required)`;
  }

  return { ...acc, [key]: fn };
}, {});

// ---- component

...

MyComponent.propTypes = {
  text1: AnnotatedPropTypes.string,
  text2: AnnotatedPropTypes.string.isRequired,
};


console.log(MyComponent.propTypes.text1.description)

(The AnnotatedPropTypes object above is just an example and probably doesnt cover all the use cases)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM