3

我注意到 react 组件有一个type.propTypes对象,它将所有 propTypes 作为键。

例如,

Component.propTypes = { initialCount: React.PropTypes.number }

好像

反应组件类型

在 Chrome 开发工具中。所以我可以使用

Object.keys(component.type.propTypes)

但我也可以获得proptypes类型以及它是否需要?

4

3 回答 3

3

并不真地。如果您检查 ReactPropTypes.js,则导出的验证方法expectedType在私有范围内使用。

查看 ReactElementValidator.js 以了解它如何调用propType 验证也很有趣。

如果您想针对原始类型进行测试,您可能会使用假道具对验证方法进行迭代调用并捕获错误,直到它不抛出,但我认为这不是您所追求的。

于 2015-11-18T22:48:13.030 回答
2

以下函数根据@M_rivermount:s 的回答提取 propTypes 的名称、类型和 isRequired。

var extractPropTypes = (component) => {
  let propTypes = component.type.propTypes;
  let propNames = Object.keys(propTypes);

  let extractPropType = (propTypes, propName) => {
      let fakeProps = {};
      fakeProps[propName] = "dummy";
      let error = propTypes[propName](fakeProps, propName);
      if (error === null) {
          return "string";
      } else {
          const EXPECTED_TYPE_PATTERN = /expected `(\w+)`/i;
          return error.toString().match(EXPECTED_TYPE_PATTERN)[1];
      }
  };

  let extractPropIsRequired = (propTypes, propName) => {
      let fakeProps = {};
      fakeProps[propName] = null;
      let error = propTypes[propName](fakeProps, propName);
      return !!error;
  };

  return propNames.map(function (propName) {
      return {
          name: propName,
          type: extractPropType(propTypes, propName),
          isRequired: extractPropIsRequired(propTypes, propName)
      }
  });
};
于 2015-11-20T12:53:18.127 回答
0

更改propTypes API后,无法直接调用 PropTypes 验证器。可以使用 Proptypes 的checkPropTypes方法 手动检查类型。

此外 checkPropTypes 不会返回任何结果,而是仅将警告记录到控制台。因此,要从类型检查中检索错误,check-prop-types是救星。(虽然这里有一个 facebook/prop-types 的 PR 以允许从 checkPropTypes 进行外部日志记录)

这是@Theodor 的代码片段的更新版本(略有改动):

import checkPropTypes from 'check-prop-types';

getPropType(propTypes, propName) {
    let fakeProps = {};
    fakeProps[propName] = "dummy";

    let error = checkPropTypes(propTypes, fakeProps, 'prop');

    // extract type from error string
    if (error !== undefined) {
        const EXPECTED_TYPE_PATTERN = /expected (\w+)/i;
        return error.toString().match(EXPECTED_TYPE_PATTERN)[1];
    } else {
        // no error - it is string
        return 'string';
    }
}

getPropIsRequired(propTypes, propName){
    let fakeProps = {};
    fakeProps[propName] = null;
    let error =  checkPropTypes(propTypes,fakeProps);
    return !!error;
};

extractTypes(component) {
    let type_map = {};
    let propTypes = component.type.propTypes;
    Object.keys(propTypes).forEach((propName) => {
    let type = getPropType(propTypes, propName);
    let required = getPropsIsRequired(propTypes, propName)
    type_map[propName]= {
        type:type,
        required:required
        }
    });
    return type_map;
}
于 2018-10-13T10:38:10.347 回答