可以将 propTypes 和 defaultProps 作为静态 props 放在 React class 中吗?

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

这是我已经用了很长一段时间的方法:

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

事实上,我也见过有人在构造函数之外设置初始状态。这是好习惯吗?这一直困扰着我,但我记得某个地方的讨论有人说将默认道具设置为静态不是一个好主意 - 我只是不记得为什么。

其实在性能上是完全一样的。 React.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;

他们用 propTypes 对象文字声明了一个 const,保持 class 非常干净,稍后将它们分配给静态属性。我个人喜欢这种方法:)

如果组件是无状态的,这意味着它根本不会改变自己的状态,您应该将其声明为无状态组件 (export default function MyComponent(props)) 并在外部声明 propTypes

将初始状态声明放在构造函数中是否是一种好习惯取决于您。在我们的项目中,我们在 componentWillMount() 中声明初始状态只是因为我们不喜欢必须与构造函数一起使用的 super(props) 样板文件。

es2015 当前不支持非函数属性 类。它是 es2016 的提案。第二种方法要方便得多,但需要一个插件来支持语法 (theres a very common babel plugin for it).

另一方面,大量的开源项目开始将 proptype 视为 TypeScript 接口或 ActionConstants,并实际创建单独的 folders/files 来容纳各种组件 prop 类型,然后导入到组件中.

总之,两种语法都可以使用。但是如果你只想严格使用 ES2015,规范中还不支持后一种语法。

哦,是的,Babel (或其他转译器)

完全合法
class DataLoader extends React.Component {
  static propTypes = {
    onFinishedLoading: PropTypes.func
  }

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

...无论如何它都会被转译成这个。

class DataLoader extends React.Component {}

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

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

静态字段在后台被转换为 class 对象的属性。 Look here at Babel REPL.

此外,直接在 class 正文中分配 state 或其他 class fields 会被转译到 构造函数.