React prop类型检查,如何声明“任何组件”?

时间:2018-12-22 00:20:32

标签: javascript reactjs react-proptypes

考虑一下具有以下思想的元素:

function TheElement(props) {
    const {SubElement, value} = props;
    const display = value/2;
    return <><div>some header</div>
        <div><SubElement data={display}/></div>
    </>
}
TheElement.propTypes = {
    value: PropTypes.number.isRequired,
    SubElement: PropTypes.element.isRequired
}

在类似情况下使用:

function Displayer(props) {
    generateElement = function() {
        //something to dynamically generate the element
        return (props) => return <div>{props.value}</div>
    }
    return <div>
        <TheElement value={10} SubElement={generateElement()}/>
    </div>
}

虽然代码有效,但控制台确实显示警告:

  

警告:道具类型失败:提供给SubElement的类型function的道具TheElement无效,应该有一个ReactElement。

那么我该如何反应一个属性是“任何元素”?如果我给它一个PropTypes.func作为类型,它将在类类方法上失败,但是即使我使它同时接受funcobject,它也没有用。因为这并不能帮助我防止提供不会折叠到react可渲染对象的随机函数。

1 个答案:

答案 0 :(得分:1)

您会收到警告,因为(props) => return <div>{props.value}</div>是组件而不是元素。元素是<SubElement />的结果。请尝试以下操作,您将不再收到警告:

function TheElement(props) {
    const { SubElement, value } = props;
    const display = value/2;
    return (
        <>
            <div>some header</div>
            <div>{SubElement}</div>
        </>
    )
}

TheElement.propTypes = {
    value: PropTypes.number.isRequired,
    SubElement: PropTypes.element.isRequired
}


function Displayer(props) {
    generateElement = function() {
        return <div>Some Text</div>
    }
    return (
        <div>
            <TheElement value={10} SubElement={generateElement()}/>
        </div>
    )
}

要验证组件,我相信您最好的方法是使用Proptypes.func。这是因为prop-types无法知道函数是否会导致有效的react元素-这将在应用方括号语法糖(即评估<YourComponent />)时确定。您可以查看道具类型source code,以了解它仅查看传递给组件的道具(即未评估的函数)。

您可以编写一个自定义的验证器,对通过的prop进行评估,然后确保它返回有效的react元素,但是这样效率太低了吗?此外,您还必须知道在验证期间要传递给组件的道具。只是为了好玩,假设您的组件不需要道具,您可以执行以下操作:

customProp: function(props, propName, componentName) {
    if (!React.isValidElement(props[propName]({}))) {
        return new Error()
    }
}

有更多有关react组件和元素here的信息。