Comment définir les accessoires par défaut du composant sur le composant React

135

J'utilise le code ci-dessous pour définir les accessoires par défaut sur un composant React mais cela ne fonctionne pas. Dans la render()méthode, je peux voir que la sortie "accessoires non définis" a été imprimée sur la console du navigateur. Comment puis-je définir une valeur par défaut pour les accessoires du composant?

export default class AddAddressComponent extends Component {

render() {
   let {provinceList,cityList} = this.props
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props')
    }
    ...
}

AddAddressComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
}

AddAddressComponent.propTypes = {
  userInfo: React.PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,
}
Joey Yi Zhao
la source

Réponses:

139

Vous avez oublié de fermer le Classsupport.

class AddAddressComponent extends React.Component {
  render() {
    let {provinceList,cityList} = this.props
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props')
    } else {
      console.log('defined props')
    }

    return (
      <div>rendered</div>
    )
  }
}

AddAddressComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
};

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
};

AddAddressComponent.propTypes = {
  userInfo: React.PropTypes.object,
  cityList: React.PropTypes.array.isRequired,
  provinceList: React.PropTypes.array.isRequired,
}

ReactDOM.render(
  <AddAddressComponent />,
  document.getElementById('app')
)
<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>
<div id="app" />

Serhii Baraniuk
la source
92

Pour ceux qui utilisent quelque chose comme babel stage-2 ou transform-class-properties :

import React, { PropTypes, Component } from 'react';

export default class ExampleComponent extends Component {
   static contextTypes = {
      // some context types
   };

   static propTypes = {
      prop1: PropTypes.object
   };

   static defaultProps = {
      prop1: { foobar: 'foobar' }
   };

   ...

}

Mettre à jour

À partir de React v15.5, a PropTypesété déplacé hors du package principal React ( lien ):

import PropTypes from 'prop-types';

Éditer

Comme l'a souligné @johndodo, staticles propriétés de classe ne font en fait pas partie de la spécification ES7, mais ne sont actuellement prises en charge que par babel. Mis à jour pour refléter cela.

treyhakanson
la source
merci pour la réponse, mais je voulais en savoir un peu plus à ce sujet, alors j'ai jeté un coup d'œil à react/ nativedoc et je n'ai pas pu les trouver, où est le doc pour cela?
farmcommand2
Je ne pense pas que ce soit explicitement dans la documentation React, mais si vous comprenez quelles staticsont les variables de classe, cela a du sens, alors je suggère de les lire sur MDN . Fondamentalement, la syntaxe de la documentation est équivalente à cela car les deux ajoutent des informations sur les accessoires à la classe elle-même, pas sur les instances individuelles.
treyhakanson
1
l'importation est modifiée en: importer des PropTypes à partir de 'prop-types';
tibi
1
@treyhakanson Le lien MDN ne parle que de méthodes statiques, pas de variables. Je n'ai pas trouvé de référence pour les variables de classe statiques, à l'exception de Babel . Est-ce une propriété ES7 acceptée?
johndodo
15

Vous devez d'abord séparer votre classe des autres extensions, car vous ne pouvez pas l'étendre AddAddressComponent.defaultPropsau classlieu de la déplacer à l'extérieur.

Je vous recommanderai également de lire sur le cycle de vie du constructeur et de React: voir Spécifications des composants et cycle de vie

Voici ce que vous voulez:

import PropTypes from 'prop-types';

class AddAddressComponent extends React.Component {
  render() {
    let { provinceList, cityList } = this.props;
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props');
    }
  }
}

AddAddressComponent.contextTypes = {
  router: PropTypes.object.isRequired
};

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
};

AddAddressComponent.propTypes = {
  userInfo: PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,
}

export default AddAddressComponent;
Ilanus
la source
Êtes-vous sûr qu'ils ont besoin du constructoret componentWillReceiveProps? Il me semble que l'OP vient d'oublier un crochet fermant pour sa déclaration de classe.
ivarni
@ivarni pas nécessairement mais il est important qu'il comprenne le cycle de vie, le constructeur et les extensions de classe. donc il saura ce qu'il fait. donc j'ai ajouté quelques liens externes
Ilanus
2
Assez juste, je pense juste que dire "vous devez" n'est pas strictement correct. Je préfère dire quelque chose du genre "vous pouvez ajouter ces méthodes pour observer le cycle de vie" . Sinon, bonne réponse :)
ivarni
9

Vous pouvez également utiliser l'affectation de destruction.

class AddAddressComponent extends React.Component {
  render() {

    const {
      province="insertDefaultValueHere1",
      city="insertDefaultValueHere2"
    } = this.props

    return (
      <div>{province}</div>
      <div>{city}</div>
    )
  }
}

J'aime cette approche car vous n'avez pas besoin d'écrire beaucoup de code.

Sam Henderson
la source
2
Le problème que je vois ici est que vous souhaiterez peut-être utiliser des accessoires par défaut dans plusieurs méthodes.
Gerard Brull
5

utiliser une valeur statique par défaut

export default class AddAddressComponent extends Component {
    static defaultProps = {
        provinceList: [],
        cityList: []
    }

render() {
   let {provinceList,cityList} = this.props
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props')
    }
    ...
}

AddAddressComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
}

AddAddressComponent.propTypes = {
  userInfo: React.PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,
}

Tiré de: https://github.com/facebook/react-native/issues/1772

Si vous souhaitez vérifier les types, voyez comment utiliser PropTypes dans la réponse de treyhakanson ou d'Ilan Hasanov, ou consultez les nombreuses réponses dans le lien ci-dessus.

Brandon Keith Biggs
la source
4

Vous pouvez définir les accessoires par défaut en utilisant le nom de la classe comme indiqué ci-dessous.

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

// Specifies the default values for props:
Greeting.defaultProps = {
  name: 'Stranger'
};

Vous pouvez utiliser la méthode recommandée par React à partir de ce lien pour plus d'informations

Rohith Murali
la source
4

Pour un accessoire de type de fonction, vous pouvez utiliser le code suivant:

AddAddressComponent.defaultProps = {
    callBackHandler: () => {}
};

AddAddressComponent.propTypes = {
    callBackHandler: PropTypes.func,
};
Wolfack
la source
2

Si vous utilisez un composant fonctionnel, vous pouvez définir des valeurs par défaut dans l'affectation de déstructuration, comme ceci:

export default ({ children, id="menu", side="left", image={menu} }) => {
  ...
};
Brian Burns
la source
0
class Example extends React.Component {
  render() {
    return <h1>{this.props.text}</h1>;
  }
}

Example.defaultProps = { text: 'yo' }; 
Lepkem
la source