给定一个呈现其子组件的简单组件:
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>
警告:失败的道具类型:类型数组的无效道具子元素
提供给ContainerComponent,期望对象。
如果我把它设置为一个数组,如果我只给它一个子数组,它就会失败,即:
<ContainerComponent>
<div>1</div>
</ContainerComponent>
警告:失败的道具类型:类型对象的无效道具子
提供给ContainerComponent,期望数组。
请建议,我不应该打扰做一个propTypes检查子元素?
尝试自定义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:
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 />
这里的答案似乎并没有完全涵盖对孩子们的检查。node和object太允许,我想检查确切的元素。这是我最终使用的:
使用oneOfType([])允许使用单个或一组子元素
对于单个子数组和数组子数组,分别使用shape和arrayOf(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