简体   繁体   English

从组件中提取 proptypes、isRequired 和 defaultProps

[英]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.这将打印一个 object,所有 propNames 为 function。 I am not able to get the type from the object.我无法从 object 中获取类型。 How do I get the proptype (in this example string) and "isRequired" from this component?如何从此组件中获取 proptype(在此示例字符串中)和“isRequired”? I want to use it for automatically render a table with all possible propNames + PropType + isRequired + defaultPropType我想用它来自动渲染一个包含所有可能的 propNames + PropType + isRequired + defaultPropType 的表

You cant retrieve the information you are looking for by reading the propType properties.您无法通过读取 propType 属性来检索您要查找的信息。 Each item in the propTypes is actually a validation wrapper function that obscures the actual type validation. propTypes 中的每个项目实际上是一个验证包装器 function,它掩盖了实际的类型验证。

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.您的方案的另一个选项是使用包含所需信息的组件创建和导出另一个 static 属性。 Then create a utility method to map your property data into PropTypes然后创建一个实用方法将您的属性数据 map 转换为 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:第二种选择可能是包装 PropTypes object 并添加您自己的注释,例如:


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) (上面的 AnnotatedPropTypes object 只是一个示例,可能并未涵盖所有用例)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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