Is it OK to put propTypes and defaultProps as static props inside React class?

Oh yes, it's totaly legit with Babel (or other transpilers)

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

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

...as it gets transpiled to this anyway.

class DataLoader extends React.Component {}

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

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

Static fields get transpiled as properties on the class object under the hood. Look here at Babel REPL.

Moreover, assigning state or other class fields directly in the class body gets transpiled into the constructor.


In fact, it's exactly the same in terms of performance. React.JS is a relatively new technology, so it's not clear yet what are considered good practices or don't. If you want to trust someone, check this AirBNB's styleguide:

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;

They are declaring a const with the propTypes object literals, keep the class pretty clean and assign them later to the static properties. I personally like this approach :)


non-function properties are not currently supported for es2015 classes. its a proposal for es2016. the second method is considerably more convenient, but a plugin would be required to support the syntax (theres a very common babel plugin for it).

On the other end, a hand full of open source projects are beginning to treat proptypes like TypeScript interfaces, or ActionConstants and actually create separate folders/files that house various component prop types and are then imported into the component.

So in summary, both syntaxes are ok to use. but if you want to only use strictly ES2015, the latter syntax is not yet supported in the specification.