Как установить реквизиты компонента по умолчанию для компонента React

135

Я использую приведенный ниже код, чтобы установить свойства по умолчанию для компонента React, но он не работает. В этом render()методе я вижу, что вывод «undefined props» был напечатан на консоли браузера. Как я могу определить значение по умолчанию для свойств компонента?

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,
}
Джои Йи Чжао
источник

Ответы:

139

Вы забыли закрыть Classскобу.

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" />

Сергей Баранюк
источник
92

Для тех, кто использует что-то вроде babel stage-2 или 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' }
   };

   ...

}

Обновить

Начиная с React v15.5, PropTypesбыл перемещен из основного пакета React Package ( ссылка ):

import PropTypes from 'prop-types';

редактировать

Как указывает @johndodo, staticсвойства класса на самом деле не являются частью спецификации ES7, а в настоящее время поддерживаются только babel. Обновлено, чтобы отразить это.

treyhakanson
источник
спасибо за ответ, но я хотел узнать об этом немного больше, поэтому посмотрел react/ nativedoc и не смог их найти, где для этого документ?
farmcommand2
Я не думаю, что это явно указано в документации React, но если вы понимаете, что такое staticпеременные класса, это имеет смысл, поэтому я предлагаю прочитать о них в MDN . По сути, синтаксис в документации эквивалентен этому, потому что оба добавляют информацию о реквизитах к самому классу, а не к отдельным экземплярам.
treyhakanson
1
импорт изменен на: import PropTypes from 'prop-types';
tibi
1
@treyhakanson Ссылка MDN говорит только о статических методах, а не о переменных. Мне не удалось найти ссылку на статические переменные класса, кроме Babel . Это приемлемое свойство ES7?
johndodo
15

Сначала вам нужно отделить свой класс от дополнительных расширений, которые вы не можете расширять AddAddressComponent.defaultPropsвнутри, classвместо этого переместите его наружу.

Я также порекомендую вам прочитать о жизненном цикле конструктора и React: см. Спецификации компонентов и жизненный цикл.

Вот что вам нужно:

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
источник
Вы уверены, что им нужны constructorи componentWillReceiveProps? Мне кажется, OP просто забыл закрывающую скобку для объявления своего класса.
ivarni 05
@ivarni не обязательно, но важно, чтобы он понимал жизненный цикл, конструктор и расширения класса. так он будет знать, что делает. поэтому я добавил несколько внешних ссылок
Иланус
2
Честно говоря, я просто думаю, что говорить «вам нужно» не совсем правильно. Я бы предпочел сказать что-то вроде «вы можете добавить эти методы для наблюдения за жизненным циклом» . В противном случае хороший ответ :)
ivarni 05
9

Вы также можете использовать назначение «Разрушение».

class AddAddressComponent extends React.Component {
  render() {

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

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

Мне нравится этот подход, так как вам не нужно писать много кода.

Сэм Хендерсон
источник
2
Проблема, которую я вижу здесь, заключается в том, что вы можете использовать свойства по умолчанию в нескольких методах.
Gerard Brull
5

используйте статические свойства defaultProps, например:

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

Взято с: https://github.com/facebook/react-native/issues/1772

Если вы хотите проверить типы, посмотрите, как использовать PropTypes в ответах трейхакансона или Илана Гасанова, или просмотрите множество ответов в приведенной выше ссылке.

Брэндон Кейт Биггс
источник
4

Вы можете установить свойства по умолчанию, используя имя класса, как показано ниже.

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

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

Вы можете использовать рекомендуемый способ React по этой ссылке для получения дополнительной информации

Рохит Мурали
источник
4

Для свойства типа функции вы можете использовать следующий код:

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

AddAddressComponent.propTypes = {
    callBackHandler: PropTypes.func,
};
Wolfack
источник
2

Если вы используете функциональный компонент, вы можете определить значения по умолчанию в назначении деструктуризации, например:

export default ({ children, id="menu", side="left", image={menu} }) => {
  ...
};
Брайан Бернс
источник
0
class Example extends React.Component {
  render() {
    return <h1>{this.props.text}</h1>;
  }
}

Example.defaultProps = { text: 'yo' }; 
Lepkem
источник