this.props.children的PropTypes应该是什么?

给定一个呈现其子组件的简单组件:

class ContainerComponent extends Component {
static propTypes = {
children: PropTypes.object.isRequired,
}


render() {
return (
<div>
{this.props.children}
</div>
);
}
}


export default ContainerComponent;

问:儿童道具的道具类型应该是什么?

当我将它设置为一个对象时,当我使用有多个子组件时,它会失败:

<ContainerComponent>
<div>1</div>
<div>2</div>
</ContainerComponent>

警告:失败的道具类型:类型array的无效道具children 提供给ContainerComponent,期望object.

如果我把它设置为一个数组,如果我只给它一个子数组,它就会失败,即:

<ContainerComponent>
<div>1</div>
</ContainerComponent>

警告:失败的道具类型:类型对象的无效道具子 提供给ContainerComponent,期望数组

请建议,我不应该打扰做一个propTypes检查子元素?

183898 次浏览

尝试使用oneOfTypePropTypes.node这样做

import PropTypes from 'prop-types'


...


static propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]).isRequired
}

static propTypes = {
children: PropTypes.node.isRequired,
}

尝试自定义propTypes:

 const  childrenPropTypeLogic = (props, propName, componentName) => {
const prop = props[propName];
return React.Children
.toArray(prop)
.find(child => child.type !== 'div') && new Error(`${componentName} only accepts "div" elements`);
};




static propTypes = {


children : childrenPropTypeLogic


}

小提琴

const {Component, PropTypes} = React;


const  childrenPropTypeLogic = (props, propName, componentName) => {
var error;
var prop = props[propName];
    

React.Children.forEach(prop, function (child) {
if (child.type !== 'div') {
error = new Error(
'`' + componentName + '` only accepts children of type `div`.'
);
}
});
    

return error;
};
    

  



class ContainerComponent extends Component {
static propTypes = {
children: childrenPropTypeLogic,
}


render() {
return (
<div>
{this.props.children}
</div>
);
}
}






class App extends Component {
render(){
return (
<ContainerComponent>
<div>1</div>
<div>2</div>
</ContainerComponent>
)
}
}


ReactDOM.render(<App /> , document.querySelector('section'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<section />

对我来说,这取决于组件。如果你知道你需要填充什么,那么你应该尝试指定独占的,或多个类型使用:

PropTypes.oneOfType

如果你想引用一个React组件,那么你将寻找

PropTypes.element

尽管如此,

PropTypes.node

描述任何可以呈现的东西——字符串、数字、元素或这些东西的数组。如果这适合你,那么这就是方法。

非常泛型组件可以有许多类型的子组件,你也可以使用下面的。但是我不建议这样做。正如下面的评论中提到的,它确实在某种程度上破坏了使用PropTypes的意义,通常还有其他方法来指定组件所需的内容。还要记住,eslint和ts可能(可能)不喜欢这种缺乏特异性:

PropTypes.any

如果您想精确匹配某个组件类型,请选中此选项

MenuPrimary.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(MenuPrimaryItem),
PropTypes.objectOf(MenuPrimaryItem)
])
}

如果您希望精确匹配某些组件类型,请选中此选项

const HeaderTypes = [
PropTypes.objectOf(MenuPrimary),
PropTypes.objectOf(UserInfo)
]


Header.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.oneOfType([...HeaderTypes])),
...HeaderTypes
])
}

这里的答案似乎并没有完全涵盖对孩子们的检查。nodeobject太允许,我想检查确切的元素。这是我最终使用的:

  • 使用oneOfType([])来允许单个或数组的子元素
  • shapearrayOf(shape({}))分别用于单个子对象和数组子对象
  • 为子元素本身使用oneOf

最后,是这样的:

import PropTypes from 'prop-types'
import MyComponent from './MyComponent'


children: PropTypes.oneOfType([
PropTypes.shape({
type: PropTypes.oneOf([MyComponent]),
}),
PropTypes.arrayOf(
PropTypes.shape({
type: PropTypes.oneOf([MyComponent]),
})
),
]).isRequired

这个问题帮助我更清楚地解决了这个问题:https://github.com/facebook/react/issues/2979

PropTypes文档有以下内容

// Anything that can be rendered: numbers, strings, elements or an array
// (or fragment) containing these types.
optionalNode: PropTypes.node,

因此,你可以使用PropTypes.node来检查对象或对象数组

static propTypes = {
children: PropTypes.node.isRequired,
}

例子:

import React from 'react';
import PropTypes from 'prop-types';


class MenuItem extends React.Component {
render() {
return (
<li>
<a href={this.props.href}>{this.props.children}</a>
</li>
);
}
}


MenuItem.defaultProps = {
href: "/",
children: "Main page"
};


MenuItem.propTypes = {
href: PropTypes.string.isRequired,
children: PropTypes.string.isRequired
};


export default MenuItem;

图片:如果预期的类型不同,在控制台显示错误

图片:显示你在控制台错误,如果预期的类型是不同的

如果你想包含渲染道具组件:

  children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
PropTypes.func
])

根据proptype文档element用于React元素,children是其中之一:

// A React element.
optionalElement: PropTypes.element,

然后你可以将它与arrayOf结合

< p >组件。propTypes = { 孩子们:PropTypes.arrayOf .isRequired (PropTypes.element), < / p >};

然后它将至少需要一个children