Como definir adereços padrão do componente no componente React

134

Eu uso o código abaixo para definir adereços padrão em um componente React, mas ele não funciona. No render()método, vejo que a saída "objetos indefinidos" foi impressa no console do navegador. Como posso definir um valor padrão para os componentes do 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
fonte

Respostas:

139

Você esqueceu de fechar o Classsuporte.

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

Para aqueles que usam algo como 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' }
   };

   ...

}

Atualizar

A partir do React v15.5, PropTypesfoi movido para fora do pacote principal do React ( link ):

import PropTypes from 'prop-types';

Editar

Conforme apontado pelo @johndodo, staticas propriedades da classe não fazem parte da especificação do ES7, mas atualmente são suportadas apenas pelo babel. Atualizado para refletir isso.

treyhakanson
fonte
obrigado pela resposta, mas eu queria aprender um pouco mais sobre isso, então dei uma olhada no react/ nativedoc e não consegui encontrá-los. Onde está o documento para isso?
farmcommand2
Eu não acho isso explicitamente nos documentos do React, mas se você entender quais staticsão as variáveis ​​de classe, faz sentido, então sugiro que leia sobre elas no MDN . Basicamente, a sintaxe na documentação é equivalente a isso porque ambos estão adicionando informações sobre os props à própria classe, não às instâncias individuais.
treyhakanson
1
a importação é alterada para: import PropTypes de 'prop-types';
Tibi
1
@treyhakanson O link MDN fala apenas sobre métodos estáticos, não variáveis. Não consegui encontrar uma referência para variáveis ​​de classe estática, exceto Babel . Esta é uma propriedade aceita do ES7?
Johndodo 12/12
15

Primeiro você precisa separar sua classe a partir da nova extensão ex você não pode estender AddAddressComponent.defaultPropsdentro da classvez movê-lo fora.

Também recomendo que você leia sobre o ciclo de vida do Construtor e do React: consulte Especificações do componente e ciclo de vida

Aqui está o que você deseja:

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
fonte
Tem certeza de que eles precisam do constructore componentWillReceiveProps? Parece-me que o OP esqueceu um colchete para a declaração de classe.
Ivarni 5/08
@ivarni não necessariamente, mas é importante que ele entenda o ciclo de vida, o construtor e as extensões de classe. para que ele saiba o que está fazendo. então eu adicionei alguns links externos
Ilanus
2
Justo, acho que dizer "você precisa" não é estritamente correto. Prefiro dizer algo como "você pode adicionar esses métodos para observar o ciclo de vida" . Caso contrário, boa resposta :)
ivarni
9

Você também pode usar a atribuição de Reestruturação.

class AddAddressComponent extends React.Component {
  render() {

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

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

Eu gosto dessa abordagem, pois você não precisa escrever muito código.

Sam Henderson
fonte
2
O problema que vejo aqui é que você pode usar adereços padrão em vários métodos.
Gerard Brull
5

use um padrão estático

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

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

Se você deseja verificar os tipos, veja como usar PropTypes na resposta de treyhakanson ou Ilan Hasanov ou revise as muitas respostas no link acima.

Brandon Keith Biggs
fonte
4

Você pode definir os acessórios padrão usando o nome da classe, como mostrado abaixo.

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

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

Você pode usar a maneira recomendada do React neste link para obter mais informações

Rohith Murali
fonte
4

Para um tipo de função prop, você pode usar o seguinte código:

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

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

Se você estiver usando um componente funcional, poderá definir padrões na atribuição de desestruturação, assim:

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

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