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.