Подтвердить что ты не робот

ReactJs: Какими должны быть PropTypes для этого .props.children?

Учитывая простой компонент, который отображает его дочерние элементы:

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

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

export default ContainerComponent;

Вопрос: Каким должен быть propType поддержки детей?

Когда я устанавливаю его как объект, он терпит неудачу, когда я использую компонент с несколькими дочерними элементами:

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

Предупреждение: Неверный тип prop: Неверный prop children типа arrayподается на ContainerComponent, ожидается object.

Если я устанавливаю его как массив, он будет терпеть неудачу, если я дам ему только один ребенок, т.е.:

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

Предупреждение: Неверный тип опоры: недопустимые дочерние элементы типа типа поставляемый в ContainerComponent, ожидаемый массив.

Пожалуйста, посоветуйте, не нужно ли мне делать проверку propTypes для дочерних элементов?

4b9b3361

Ответ 1

Попробуйте что-то подобное, используя oneOfType или PropTypes.node

import PropTypes from 'prop-types'

...

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

или

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

Ответ 2

Для меня это зависит от компонента. Если вы знаете, что вам нужно, чтобы его заполнили, вам следует попытаться указать исключительно или несколько типов, используя:

PropTypes.oneOfType 

Однако в основном я нахожу, с более универсальными компонентами, у которых может быть много типов детей, я рад использовать:

PropTypes.any

Если вы хотите обратиться к компоненту React, то вы будете искать

PropTypes.element

Несмотря на то,

PropTypes.node

описывает все, что может быть показано - строки, числа, элементы или массив этих вещей. Если это вам подходит, то это способ.

Ответ 3

Попробуйте пользовательские 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 />