React.PropType有两种可能的形状

时间:2016-11-29 20:05:34

标签: reactjs react-proptypes

背景:我正在尝试为维度规范指定道具类型,我可以指定显式值,也可以指定要评估的最小值和最大值。这将由图像组件使用,该组件将评估图像是否是用户生成的输入的可接受高度和宽度。

  

抽象的目标是让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的限制?有这种问题的标准解决方案吗?

1 个答案:

答案 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
         })
     ])
 };
相关问题