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

Posted

技术标签:

【中文标题】可以将 propTypes 和 defaultProps 作为静态 props 放在 React 类中吗?【英文标题】:Is it OK to put propTypes and defaultProps as static props inside React class? 【发布时间】:2016-08-15 03:58:54 【问题描述】:

这是我很长一段时间以来一直这样做的方式:

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>
  

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

【问题讨论】:

您询问过静态 getter,但您的示例是静态类属性,您是否想知道两者? 抱歉,静态类属性。我会编辑 【参考方案1】:

其实在性能上是完全一样的。 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,保持类相当干净,然后将它们分配给静态属性。我个人喜欢这种方法:)

【讨论】:

使用实验性功能后,我想我更愿意在更稳定的提案方面犯错。 Airbnb 的风格从未误导过我。 对不起,但是分开 propTypes 声明有什么意义呢? - 有什么优势? 在我的例子中,确实没有优势,这只是一种自以为是的声明方式。但它在您可能希望跨组件重用数据结构并且不想在每个组件中重复 propTypes 声明的情况下很有用:) 在 2020 年,带有 React 16+ 和目标环境(或 polyfill)中可用的扩展语法,Component.propTypes = some: 'val', ...Related.propTypes, nestedChildProps: ...NestedChild.propTypes , override: 'val' 和整个厨房水槽都完全符合您在运行时的期望。短绒已经变得很好,但即使在今天,你也必须接受权衡。【参考方案2】:

哦,是的,使用 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: () => 
;

静态字段在底层被转换为类对象的属性。 Look here at Babel REPL.

此外,直接在类主体中分配 state 或其他 class fields 会被转译为 构造函数

【讨论】:

【参考方案3】:

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

另一方面,大量开源项目开始处理诸如 TypeScript 接口或 ActionConstants 之类的 proptypes,并实际创建单独的文件夹/文件来容纳各种组件 prop 类型,然后将其导入到组件中。

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

以上是关于可以将 propTypes 和 defaultProps 作为静态 props 放在 React 类中吗?的主要内容,如果未能解决你的问题,请参考以下文章

PropTypes.element和PropTypes.node的区别

React——props的使用以及propTypes

React中的PropTypes详解

React的PropTYpes

暴露 React 组件 PropTypes

react的传值类型PropTypes简单说明