是否可以使用React.PropTypes
对单个道具进行多次验证。特别想要混合自定义验证和库存验证。
我有两个道具,一个对象options
和一个字符串value
。我想检查props.value
是一个字符串,但也是对象上的一个键。使用coffeescript看起来像:
propTypes:
options: React.PropTypes.Object.isRequired
value: (props, propName, componentName) ->
unless props[propName] of props.options
new Error('my custom message')
这很好用,但我也想确保我的值是一个字符串类型。我确信我可以手动坚持自定义函数中的验证没问题,但理想情况下,我只想使用React.PropTypes.string.isRequired
。香港专业教育学院尝试将其放入自定义功能并执行它,但这不起作用。以下内容也不起作用:
value: React.PropTypes.string.isRequired && (props, propName, componentName) ->
unless props[propName] of props.options
new Error('my custom message')
有没有办法让使用内置验证器的反应来工作,或者在我的函数中重写它是唯一的选择?
答案 0 :(得分:3)
来自文档中的Reusable Components页面:
You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
因此propType不返回任何内容或错误对象。我们可以编写一个'all'函数,它接受两个propTypes并合并结果。
const allPropTypes = (...types) => (...args) => {
const errors = types.map((type) => type(...args)).filter(Boolean);
// no errors? cool!
if (errors.length === 0) return;
// collect the messages and join them together
const message = errors.map((e) => e.message).join('\n');
return new Error(message);
};
然后你可以使用它来断言多个propTypes。
propTypes = {
foo: allPropTypes(
PropTypes.string.isRequired,
(props, propName, componentName) => props.options && props.options[props[propName]]
? undefined
: new Error(
`${componentName}: expected prop ${propName}="${prop[propName]}"`
+ `to be a key of prop "options" `
+ `(one of ${Object.keys(props.options).join(', ')})`
)
)
}
注意:这些都没有经过测试,但没有语法错误!您可以使用babel将其编译为es3,或者手动将其转换为CS。
答案 1 :(得分:0)
如果您按照this链接,Ian Thomas解释了createChainableTypeChecker方法的使用方法,该方法在反应中但未作为propTypes模块的一部分导出。本文清楚地解释了如何使用相同的代码链接验证调用:
function createChainableTypeChecker(validate) {
function checkType(isRequired, props, propName, componentName, location) {
componentName = componentName || ANONYMOUS;
if (props[propName] == null) {
var locationName = ReactPropTypeLocationNames[location];
if (isRequired) {
return new Error(
("Required " + locationName + " `" + propName + "` was not specified in ") +
("`" + componentName + "`.")
);
}
return null;
} else {
return validate(props, propName, componentName, location);
}
}
var chainedCheckType = checkType.bind(null, false);
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
}