背景:我正在尝试为维度规范指定道具类型,我可以指定显式值,也可以指定要评估的最小值和最大值。这将由图像组件使用,该组件将评估图像是否是用户生成的输入的可接受高度和宽度。
抽象的目标是让React props值解析为两种可能的形状之一。
宽度的显式值将具有以下形状:
{
width: PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
})
}
min和max 值将具有以下形状:
{
width: PropTypes.shape({
min: {
value: PropTypes.number.isRequired,
error: PropTypes.string
}, max: {
value: PropTypes.number.isRequired,
error: PropTypes.string
}
})
}
编辑:正如在接受的答案中所指出的,这个块中有一个我没有抓到的错误。由于某种原因,它没有给我一个运行时错误,但这不是嵌套形状的工作示例,请参阅正确语法的答案。
如果我尝试其中任何一种方法并且属性匹配,那么一切都按预期工作所以我可以安全地假设错误来自下面的代码。
我尝试使用React typechecking documentation中的OptionalUnion,通过 PropTypes.oneOfType ,并使用以下语法。
{
width: PropTypes.oneOfType([
PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
}), PropTypes.shape({
min: {
value: PropTypes.number.isRequired,
error: PropTypes.string
}, max: {
value: PropTypes.number.isRequired,
error: PropTypes.string
}
})
])
}
当我尝试这个时,我得到了回复
Warning: Failed propType: checker is not a function Check the render method of 'MyParentContainer'.
如果我在没有PropTypes.oneOfType
方法的情况下使用任何一种形状,调试器中没有任何投诉,一切都按预期运行。 PropTypes.oneOf
引发了一个看似更糟的错误:
warning.js:45Warning: Failed propType: Invalid prop 'dimensions.width' of value '[object Object]' supplied to 'MyComponent', expected one of [null,null]. Check the render method of 'MyParentContainer'.
是否有人知道此语法是否已关闭或者这是PropTypes.oneOfType的限制?有这种问题的标准解决方案吗?
答案 0 :(得分:6)
PropTypes.shape
不是递归的,你必须为子结构重复它,例如。
width: PropTypes.shape({
min: PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
}).isRequired,
max: PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
}).isRequired
})
因此,整个验证器应该是:
const propTypes = {
width: PropTypes.oneOfType([
PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
}),
PropTypes.shape({
min: PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
}).isRequired,
max: PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
}).isRequired
})
])
};
另外,我真的建议使用变量来提高可读性并防止代码重复:
const valueType = PropTypes.shape({
value: PropTypes.number.isRequired,
error: PropTypes.string
});
const propTypes = {
width: PropTypes.oneOfType([
valueType,
PropTypes.shape({
min: valueType.isRequired,
max: valueType.isRequired
})
])
};