我有一个用例,我需要编写一个自定义的React PropType
验证器。在该检查器中,我想做两件事:1)验证对象内部的动态生成的道具名称都是md5哈希,以及2)验证"形状"连接到每个道具的物体。
问题#1我已经想通了; #2让我有所收获。这里有一些代码可以说明:
说我有这样一个对象:
{
key1: {
byHash: {
'<some md5 hash>': { ... }
}
},
key2: {
byHash: {
'<some md5 ash>': { ... }
}
}
}
检查此对象时,我想确保密钥确实是md5哈希,然后我想确保分配给key1
和{{1的每个对象中的密钥及其值的正确性}}。让我们说,此外,我已经创建了一个类似的验证器函数:
key2
然后我编写自定义验证器函数:
const validObjShape = PropTypes.shape({
someString: PropTypes.string.isRequired,
someBoolean: PropTypes.bool
});
我的问题 - 如上所述 - 我可以使用上面创建的const validCustomProp = (props, propName, componentName) => {
const obj = props[propName];
if (!isObject(obj)) {
return new Error(
//eslint-disable-next-line
'Invalid prop `' + propName + '`of type `' + typeof obj + '` supplied to ' +
'`' + componentName + '`, expected an object.'
);
}
if (isEmpty(obj)) {
return null;
}
forEach(obj, (v, k) => {
const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
if (!isMD5) {
throw new Error(
//eslint-disable-next-line
'Invalid dynamic key on `' + propName + '`. All keys ' +
'on this object should be md5 hashes, but we found `' + k + '` instead.'
);
}
});
// Here I want to somehow validate each object on `obj`. Something like:
// forEach(obj, (v, k) => {
// const err = validObjShape(props[propName], k, componentName);
// if (err) {
// // throw some err...
// }
// }
return null;
};
来验证嵌套在validObjShape
中的对象的形状。我认为直接调用验证器fn将在React的v16中被禁止(参见this post)。那么现在怎样才能实现呢?
答案 0 :(得分:2)
PropTypes
- 而不是自己使用PropTypes
。正如文档declaring PropTypes
is fine中所述,只需使用prop-types库。
所以,
const apiShape = React.PropTypes.shape({
body: customValidator,
statusCode: React.PropTypes.number.isRequired
}).isRequired;
只需更改为
import PropTypes from 'prop-types';
const apiShape = React.PropTypes.shape({
body: customValidator,
statusCode: PropTypes.number.isRequired
}).isRequired;
并且customValidator
不必更改。
您可以在来源中自行验证:ElementCreation =&gt; ElementValidation in DEV mode =&gt; Validating prop types =&gt; calling checkPropTypes已被移动here
React强烈相信类型安全,并且贬值PropTypes
似乎不太可能。它仍然存在于docs (from the master)
这是新行为,只有在从React.PropTypes迁移到prop-types包时才会遇到它。
所以不推荐使用以下内容
Object.keys(props[propName]).forEach(k => {
// const v = props[propName][k];
const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
if (!isMD5) {
return new Error(
'Not an md5'
);
}
return validObjShape(props[propName], k, componentName);
});
而是使用checkPropTypes
:
const validObjShape = PropTypes.shape({
someString: PropTypes.string.isRequired,
someBoolean: PropTypes.bool
});
const validCustomProp = (props, propName, componentName) => {
Object.keys(props[propName]).forEach(k => {
const v = props[propName][k];
const isMD5 = (/[a-fA-F0-9]{32}/).test(k);
if (!isMD5) {
return new Error(
'Not an md5'
);
}
PropTypes.checkPropTypes({ [k]: validObjShape }, { [k]: v }, propName, componentName);
});
return null;
};