考虑一下具有以下思想的元素:
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
作为类型,它将在类类方法上失败,但是即使我使它同时接受func
和object
,它也没有用。因为这并不能帮助我防止提供不会折叠到react可渲染对象的随机函数。
答案 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的信息。