ReactJs: Was sollten die PropTypes für this.props.children sein?


265

Angesichts einer einfachen Komponente, die ihre Kinder rendert:

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

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

export default ContainerComponent;

Frage: Was soll der PropTyp der Kinder-Requisite sein?

Wenn ich es als Objekt festlege, schlägt es fehl, wenn ich die Komponente mit mehreren untergeordneten Elementen verwende:

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

Achtung: Fehler prop Typ: Ungültige prop childrenvom Typ array zugeführt ContainerComponent, erwartet object.

Wenn ich es als Array einstelle, schlägt es fehl, wenn ich ihm nur ein Kind gebe, dh:

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

Warnung: Fehlgeschlagener Requisitentyp: Ungültige Prop-Kinder des Typobjekts, das an ContainerComponent geliefert wurde, erwartetes Array.

Bitte raten Sie, sollte ich mich nicht die Mühe machen, einen propTypes-Check für untergeordnete Elemente durchzuführen?


Sie wollen wahrscheinlichnode
— Lux


2
In meiner Antwort unten finden Sie weitere Optionen. Wenn Sie jedoch nach einer untergeordneten Komponente suchen, ist dies PropTypes.element. PropTypes.node beschreibt alles, was gerendert werden kann - Zeichenfolgen, Zahlen, Elemente oder ein Array dieser Dinge. Wenn dies zu Ihnen passt, ist dies der richtige Weg.
— Gilberth

Antworten:


369

Versuchen Sie so etwas mit oneOfTypeoderPropTypes.node

import PropTypes from 'prop-types'

...

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

oder

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

1
Leider scheitert es mit dem gleichen Fehler in dem einzigen Kind Fall: „Warnung: Fehler prop Typ: Ungültige prop childrenTyps object. ... ein Array erwartet“
— d3ming

25
Das hat funktioniert! Die einfachste Lösung ist children: PropTypes.node, dass dies in beiden Fällen funktioniert hat. Vielen Dank für die Vorschläge =)
— d3ming

6
Das einzige, was diese Antwort klarer machen würde, wäre, wenn Sie einen Hinweis ähnlich der Antwort von @ggilberth einfügen würden, um zu erklären, dass React.PropTypes.nodejedes renderbare Objekt beschrieben wird.
— Theotherjim

Es ist einfach kein Array erforderlich PropTypes.node. Das behandelt die folgende Korrektur: nichts, Zeichenfolge, einzelnes Element, mehrere Elemente, Fragment, Komponente.
— Dima Tisnek

38

Für mich kommt es auf die Komponente an. Wenn Sie wissen, womit es gefüllt werden soll, sollten Sie versuchen, ausschließlich oder mehrere Typen mit folgenden Angaben anzugeben:

PropTypes.oneOfType 

Ich finde jedoch meistens, dass ich mit allgemeineren Komponenten, die viele Arten von Kindern haben können, gerne Folgendes verwende:

PropTypes.any

Wenn Sie auf eine React-Komponente verweisen möchten, suchen Sie nach

PropTypes.element

Obwohl,

PropTypes.node

beschreibt alles, was gerendert werden kann - Zeichenfolgen, Zahlen, Elemente oder ein Array dieser Dinge. Wenn dies zu Ihnen passt, ist dies der richtige Weg.


7
Proptypes.anyist zu häufig Typ. Eslint ist damit nicht zufrieden.
— Alex Shwarc

20

Die PropTypes-Dokumentation enthält Folgendes

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

Sie können also PropTypes.nodenach Objekten oder Arrays von Objekten suchen

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

12

Die Antworten hier scheinen nicht ganz die genaue Überprüfung der Kinder abzudecken. nodeund objectsind zu freizügig, ich wollte das genaue Element überprüfen. Folgendes habe ich letztendlich verwendet:

  • Verwenden Sie oneOfType([])diese Option, um einzelne oder mehrere untergeordnete Elemente zuzulassen
  • Verwenden Sie shapeund arrayOf(shape({}))für einzelne bzw. mehrere Kinder
  • Verwenden Sie oneOffür das untergeordnete Element selbst

Am Ende so etwas:

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

Dieses Problem hat mir geholfen, dies klarer herauszufinden: https://github.com/facebook/react/issues/2979


5

Wenn Sie genau einem Komponententyp entsprechen möchten, überprüfen Sie dies

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

Wenn Sie genau mit einigen Komponententypen übereinstimmen möchten, überprüfen Sie dies

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

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

2

Versuchen Sie es mit einem benutzerdefinierten PropTyp:

 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

}

Geige


0

Beispiel:

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;

Bild: Zeigt einen Fehler in der Konsole an, wenn der erwartete Typ unterschiedlich ist

Bild: Zeigt einen Fehler in der Konsole an, wenn der erwartete Typ unterschiedlich ist

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.