Cómo configurar accesorios por defecto del componente en el componente Reaccionar

135

Utilizo el siguiente código para establecer accesorios predeterminados en un componente React pero no funciona. En el render()método, puedo ver que la salida "accesorios indefinidos" se imprimió en la consola del navegador. ¿Cómo puedo definir un valor predeterminado para los accesorios del componente?

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
fuente

Respuestas:

139

Olvidaste cerrar el Classsoporte.

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
fuente
92

Para aquellos que usan algo como babel stage-2 o 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' }
   };

   ...

}

Actualizar

A partir de React v15.5, PropTypesse eliminó del paquete React principal ( enlace ):

import PropTypes from 'prop-types';

Editar

Como señaló @johndodo, staticlas propiedades de clase en realidad no son parte de la especificación ES7, sino que actualmente solo son compatibles con babel. Actualizado para reflejar eso.

treyhakanson
fuente
gracias por la respuesta, pero quería aprender un poco más sobre eso, así que eché un vistazo a react/ nativedoc y no pude encontrarlos, ¿dónde está el documento para eso?
farmcommand2
No creo que esté explícitamente en los documentos de React, pero si entiendes qué staticvariables de clase son, tiene sentido, así que sugiero leer sobre ellas en MDN . Básicamente, la sintaxis en la documentación es equivalente a esto porque ambos están agregando información sobre los accesorios a la clase en sí, no a las instancias individuales.
treyhakanson
1
la importación se cambia a: importar PropTypes desde 'prop-types';
tibi
1
@treyhakanson El enlace MDN solo habla de métodos estáticos, no de variables. No pude encontrar una referencia para las variables de clase estática, excepto para Babel . ¿Es esta una propiedad ES7 aceptada?
johndodo
15

Primero debe separar su clase de las extensiones adicionales, por ejemplo, no puede extenderlas AddAddressComponent.defaultPropsen classlugar de moverlas hacia afuera.

También le recomendaré que lea sobre el ciclo de vida de Constructor y React: consulte Especificaciones de componentes y Ciclo de vida

Esto es lo que quieres:

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
fuente
¿Estás seguro de que necesitan el constructory componentWillReceiveProps? Me parece que el OP simplemente olvidó un paréntesis de cierre para su declaración de clase.
ivarni
@ivarni no necesariamente, pero es importante que comprenda el ciclo de vida, el constructor y las extensiones de clase. entonces él sabrá lo que está haciendo. así que agregué algunos enlaces externos
Ilanus
2
Bastante justo, solo creo que decir "necesitas" no es estrictamente correcto. Prefiero decir algo como "puedes agregar estos métodos para observar el ciclo de vida" . De lo contrario, buena respuesta :)
ivarni
9

También puede usar la asignación de Destructuring.

class AddAddressComponent extends React.Component {
  render() {

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

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

Me gusta este enfoque ya que no necesitas escribir mucho código.

Sam Henderson
fuente
2
El problema que veo aquí es que es posible que desee utilizar accesorios predeterminados en varios métodos.
Gerard Brull
5

use un valor predeterminado estático como:

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,
}

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

Si desea verificar los tipos, vea cómo usar PropTypes en la respuesta de treyhakanson o Ilan Hasanov, o revise las muchas respuestas en el enlace de arriba.

Brandon Keith Biggs
fuente
4

Puede configurar los accesorios predeterminados utilizando el nombre de la clase como se muestra a continuación.

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

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

Puede usar la forma recomendada de React desde este enlace para obtener más información

Rohith Murali
fuente
4

Para un accesorio de tipo de función, puede usar el siguiente código:

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

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

Si está utilizando un componente funcional, puede definir valores predeterminados en la asignación de desestructuración, de la siguiente manera:

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

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