首页 > 解决方案 > React prop 类型检查,如何声明“任何组件”?

问题描述

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

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的道具类型无效,需要一个 ReactElement。functionTheElement

那么我如何判断一个属性是“任何元素”呢?如果我给它一个PropTypes.funcas 类型,它会在类方法上失败,但即使我让它接受两者funcobject它也没有用。因为它不会帮助我阻止提供一个不会崩溃到反应可渲染的随机函数。

标签: javascriptreactjsreact-proptypes

解决方案


您会收到警告,因为(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 无法知道一个函数是否会产生一个有效的反应元素——这将在应用括号语法糖时确定(即被<YourComponent />评估)。您可以查看 prop-types源代码 以查看它仅查看您传递给组件的道具(即未评估的函数)。

你可以编写一个自定义验证器来评估你传递的道具,然后确保它返回一个有效的反应元素,但这太低效了不是吗?此外,您必须知道在验证期间要传递给组件的道具。只是为了好玩,假设您的组件不使用任何道具,您可以执行以下操作:

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

这里有更多关于反应组件和元素的信息


推荐阅读