ReactJs: What should the PropTypes be for this.props.children?

前端 未结 8 1104
梦如初夏
梦如初夏 2020-12-04 05:49

Given a simple component that renders its children:

class ContainerComponent extends Component {
  static propTypes = {
    children: PropTypes.object.isRequ         


        
相关标签:
8条回答
  • 2020-12-04 06:32

    Try a custom 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
    
    }
    

    Fiddle

    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 />

    0 讨论(0)
  • 2020-12-04 06:33

    If you want to match exactly a component type, check this

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

    If you want to match exactly some component types, check this

    const HeaderTypes = [
      PropTypes.objectOf(MenuPrimary),
      PropTypes.objectOf(UserInfo)
    ]
    
    Header.propTypes = {
      children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.oneOfType([...HeaderTypes])),
        ...HeaderTypes
      ])
    }
    
    0 讨论(0)
  • 2020-12-04 06:45

    If you want to include render prop components:

      children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.node),
        PropTypes.node,
        PropTypes.func
      ])
    
    0 讨论(0)
  • 2020-12-04 06:46

    The answers here don't seem to quite cover checking the children exactly. node and object are too permissive, I wanted to check the exact element. Here is what I ended up using:

    • Use oneOfType([]) to allow for single or array of children
    • Use shape and arrayOf(shape({})) for single and array of children, respectively
    • Use oneOf for the child element itself

    In the end, something like this:

    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
    

    This issue helped me figure this out more clearly: https://github.com/facebook/react/issues/2979

    0 讨论(0)
  • 2020-12-04 06:54

    Example:

    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;
    

    Picture: Shows you error in console if the expected type is different

    0 讨论(0)
  • 2020-12-04 06:55

    Try something like this utilizing oneOfType or 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,
    }
    
    0 讨论(0)
提交回复
热议问题