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

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检查子元素?


当前回答

例子:

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
  ])

尝试使用oneOfType或PropTypes.node这样做

import PropTypes from 'prop-types'

...

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

or

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;

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

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

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
  ])
}

尝试自定义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 />