我注意到 react 组件有一个type.propTypes
对象,它将所有 propTypes 作为键。
例如,
Component.propTypes = { initialCount: React.PropTypes.number }
好像
在 Chrome 开发工具中。所以我可以使用
Object.keys(component.type.propTypes)
但我也可以获得proptypes类型以及它是否需要?
我注意到 react 组件有一个type.propTypes
对象,它将所有 propTypes 作为键。
例如,
Component.propTypes = { initialCount: React.PropTypes.number }
好像
在 Chrome 开发工具中。所以我可以使用
Object.keys(component.type.propTypes)
但我也可以获得proptypes类型以及它是否需要?
并不真地。如果您检查 ReactPropTypes.js,则导出的验证方法expectedType
在私有范围内使用。
查看 ReactElementValidator.js 以了解它如何调用propType 验证也很有趣。
如果您想针对原始类型进行测试,您可能会使用假道具对验证方法进行迭代调用并捕获错误,直到它不抛出,但我认为这不是您所追求的。
以下函数根据@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)
}
});
};
更改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;
}