ReactJs: Quels devraient être les PropTypes pour this.props.children?


265

Étant donné un composant simple qui rend ses enfants:

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

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

export default ContainerComponent;

Question: Quel doit être le propType de l'hélice pour enfants?

Lorsque je le définis en tant qu'objet, il échoue lorsque j'utilise le composant avec plusieurs enfants:

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

Avertissement: Type d'hélice échoué: hélice non valide childrendu type array fourni à ContainerComponent, attendue object.

Si je le définis comme un tableau, il échouera si je ne lui donne qu'un seul enfant, c'est-à-dire:

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

Avertissement: type d'accessoire ayant échoué: enfants d'accessoires non valides de l'objet type fourni à ContainerComponent, tableau attendu.

S'il vous plaît, conseillez-vous, ne devrais-je simplement pas prendre la peine de vérifier les éléments pour les enfants?


Vous voulez probablementnode
lux


2
Veuillez voir ma réponse ci-dessous qui décrit plus d'options, mais, si vous recherchez un composant enfant, c'est PropTypes.element. PropTypes.node décrit tout ce qui peut être rendu - des chaînes, des nombres, des éléments ou un tableau de ces choses. Si cela vous convient, c'est le chemin.
ggilberth

Réponses:


370

Essayez quelque chose comme ça en utilisant oneOfTypeouPropTypes.node

import PropTypes from 'prop-types'

...

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

ou

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

1
Malheureusement, il échoue avec la même erreur dans le cas enfant unique: "Avertissement: type de prop échoué: prop incorrect childrende type object... attendait un tableau."
d3ming

25
Ça a marché! La solution la plus simple est children: PropTypes.nodecelle qui a fonctionné dans les deux cas. Merci pour les suggestions =)
d3ming

6
La seule chose qui rendrait cette réponse plus claire serait que vous incluiez une note similaire à la réponse de @ggilberth pour expliquer qui React.PropTypes.nodedécrit tout objet pouvant être rendu.
theotherjim

Il n'y a pas besoin de tableau, juste PropTypes.node. Cela gère la correction suivante: rien, chaîne, élément unique, plusieurs éléments, fragment, composant.
Dima Tisnek

38

Pour moi, cela dépend du composant. Si vous savez de quoi vous avez besoin pour être rempli, vous devez essayer de spécifier exclusivement ou plusieurs types en utilisant:

PropTypes.oneOfType 

Cependant, je trouve principalement, avec des composants plus génériques qui peuvent avoir de nombreux types d'enfants, que je suis heureux d'utiliser:

PropTypes.any

Si vous voulez faire référence à un composant React, vous rechercherez

PropTypes.element

Bien que,

PropTypes.node

décrit tout ce qui peut être rendu - des chaînes, des nombres, des éléments ou un tableau de ces choses. Si cela vous convient, c'est le chemin.


7
Proptypes.anyest un type trop courant. Eslint n'est pas satisfait de cela.
Alex Shwarc

20

La documentation PropTypes contient les éléments suivants

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

Ainsi, vous pouvez utiliser PropTypes.nodepour rechercher des objets ou des tableaux d'objets

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

12

Les réponses ici ne semblent pas tout à fait couvrir la vérification exacte des enfants. nodeet objectsont trop permissifs, je voulais vérifier l'élément exact. Voici ce que j'ai fini par utiliser:

  • À utiliser oneOfType([])pour autoriser un seul ou plusieurs enfants
  • Utiliser shapeet arrayOf(shape({}))pour un seul et un ensemble d'enfants, respectivement
  • Utiliser oneOfpour l'élément enfant lui-même

En fin de compte, quelque chose comme ça:

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

Ce problème m'a aidé à comprendre cela plus clairement: https://github.com/facebook/react/issues/2979


5

Si vous souhaitez faire correspondre exactement un type de composant, cochez cette case

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

Si vous souhaitez faire correspondre exactement certains types de composants, cochez cette case

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

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

2

Essayez un accessoire personnalisé:

 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

}

Violon


0

Exemple:

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;

Image: vous montre une erreur dans la console si le type attendu est différent

Image: vous montre une erreur dans la console si le type attendu est différent

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.