Можно ли поместить propTypes и defaultProps в качестве статических реквизитов внутри класса React?

вот так я делаю это уже довольно давно:

export default class AttachmentCreator extends Component {
  render() {
    return <div>
      <RaisedButton primary label="Add Attachment" />
    </div>
  }
}

AttachmentCreator.propTypes = {
  id: PropTypes.string,
};

но я видел, что люди делают это таким образом:

export default class AttachmentCreator extends Component {
  static propTypes = {
    id: PropTypes.string,
  };

  render() {
    return <div>
      <RaisedButton primary label="Add Attachment" />
    </div>
  }
}

и на самом деле я видел людей, устанавливающих начальное состояние вне конструктора. Это хорошая практика? Это беспокоило меня, но я помню дискуссию где - то, где кто-то сказал, что установка реквизита по умолчанию как статика не является хорошей идеей-я просто не помню, почему.

4 ответов


нефункциональные свойства в настоящее время не поддерживаются для классов es2015. его предложение для es2016. второй метод значительно удобнее, но для поддержки синтаксиса (theres очень распространенный плагин babel для него).

с другой стороны, рука, полная проектов с открытым исходным кодом, начинает обрабатывать проптипы, такие как интерфейсы TypeScript или ActionConstants, и фактически создает отдельные папки/файлы, в которых размещаются различные компоненты prop типы, а затем импортируются в компонент.

Итак, в целом, оба синтаксиса в порядке использования. но если вы хотите использовать только строго ES2015, последний синтаксис не поддерживается в спецификации.


на самом деле, это точно так же, с точки зрения производительности. Реагировать.JS-относительно новая технология, поэтому пока неясно, что считается хорошей практикой или нет. Если вы хотите доверять кому-то, проверьте этот стиль AirBNB:

https://github.com/airbnb/javascript/tree/master/react#ordering

import React, { PropTypes } from 'react';

const propTypes = {
  id: PropTypes.number.isRequired,
  url: PropTypes.string.isRequired,
  text: PropTypes.string,
};

const defaultProps = {
  text: 'Hello World',
};

class Link extends React.Component {
  static methodsAreOk() {
    return true;
  }

  render() {
    return <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
  }
}

Link.propTypes = propTypes;
Link.defaultProps = defaultProps;

export default Link;

они объявляют const с литералами объекта propTypes, сохраняют класс довольно чистым и назначают их позже к статическим свойствам. Мне лично такой подход нравится:)


О да, это абсолютно законно с Babel

class DataLoader extends React.Component {
  static propTypes = {
    onFinishedLoading: PropTypes.func
  }

  static defaultProps = {
    onFinishedLoading: () => {}
  }
}

...как он получает в любом случае transpiled к этому.

class DataLoader extends React.Component {}

DataLoader.propTypes = {
  onFinishedLoading: PropTypes.func
};

DataLoader.defaultProps = {
  onFinishedLoading: () => {}
};

статические поля транспилируются как свойства класса под капотом. посмотрите здесь на Babel REPL.

более того, присваивая государство и поля класс прямо в классе получает transpiled в конструктор экземпляра.


если компонент не имеет состояния, то есть он вообще не изменяет свое собственное состояние, вы должны объявить его как компонент без состояния (export default function MyComponent(props)) и объявить propTypes снаружи.

ли это хорошая практика, чтобы поставить начальное объявление состояния в конструкторе зависит от вас. В нашем проекте мы объявляем начальное состояние в componentWillMount() просто потому, что нам не нравится super(props) boilerplate вы должны использовать с конструктором.