Airbnb React 编码规范

1,751 阅读4分钟
原文链接: qianduan.guru

Airbnb的编码规范是在业界非常流行的一套规范,而且它一直都在进化,推出最新技术的规范,例如第一时间推出了ES6的规范,让人读了感觉受益匪浅,突然发现最近更新了React的编码规范,所以第一时间翻译了过来,而且现在React如日中天,采用这个库的作为解决方案的各位,不妨读一读这个规范,借鉴学习,写出漂亮的代码。原文在此:javascript/react at master · airbnb/javascript · GitHub 欢迎各位和原文对比,并提出意见。

用更合理的方式书写React和JSX

基本规则

Class vs React.createClass vs stateless

  • 如果组件拥有内部的 state 或者 refs 的时,更推荐使用 class extends React.Component,除非你有一个非常好的理由要使用 mixin。 eslint: react/prefer-es6-class
// bad
const Listing = React.createClass({
  // ...
  render() {
    return 
{this.state.hello}
; } }); // good class Listing extends React.Component { // ... render() { return
{this.state.hello}
; } }

如果没有组件没有内部 state 或者 refs,那么普通函数 (不要使用箭头函数) 比类的写法更好:


// bad
class Listing extends React.Component {
  render() {
    return 
{this.props.hello}
; } } // bad (因为箭头函数没有“name”属性) const Listing = ({ hello }) => (
{hello}
); // good function Listing({ hello }) { return
{hello}
; }

命名

  • 扩展名:React 组件使用.jsx扩展名;
  • 文件名:文件名使用帕斯卡命名。 例如: ReservationCard.jsx
  • 引用命名:React 组件使用帕斯卡命名,引用实例采用骆驼命名。 eslint: react/jsx-pascal-case
// bad
import reservationCard from './ReservationCard';

// good
import ReservationCard from './ReservationCard';

// bad
const ReservationItem = ;

// good
const reservationItem = ;
  • 组件命名:组件名称应该和文件名一致, 例如: ReservationCard.jsx 应该有一个ReservationCard的引用名称。 但是, 如果是在目录中的组件, 应该使用 index.jsx 作为文件名 并且使用文件夹名称作为组件名:
// bad
import Footer from './Footer/Footer';

// bad
import Footer from './Footer/index';

// good
import Footer from './Footer';

声明

  • 不要使用`displayName`属性来命名组件,应该使用类的引用名称。
// bad
export default React.createClass({
  displayName: 'ReservationCard',
  // stuff goes here
});

// good
export default class ReservationCard extends React.Component {
}

对齐

// bad


// good


// 如果组件的属性可以放在一行就保持在当前一行中


// 多行属性采用缩进

  

引号

  • JSX 的属性都采用双引号,其他的 JS 都使用单引号。eslint: jsx-quotes

为什么这样做?JSX 属性 不能包含转义的引号, 所以当输入"don't"这类的缩写的时候用双引号会更方便。

标准的 HTML 属性通常也会使用双引号,所以 JSX 属性也会遵守这样的约定。

// bad


// good


// bad


// good

空格

// bad


// very bad


// bad


// good

属性

// bad


// good

// bad


// good

大括号

// bad
render() {
  return 
           
         ;
}

// good
render() {
  return (
    
      
    
  );
}

// good, when single line
render() {
  const body = 
hello
; return {body}; }

标签

// bad


// good

// bad


// good

方法

  • 在 render 方法中事件的回调函数,应该在构造函数中进行bind绑定。 eslint: react/jsx-no-bind

为什么这样做? 在 render 方法中的 bind 调用每次调用 render 的时候都会创建一个全新的函数。

// bad
class extends React.Component {
  onClickDiv() {
    // do stuff
  }

  render() {
    return 
} } // good class extends React.Component { constructor(props) { super(props); this.onClickDiv = this.onClickDiv.bind(this); } onClickDiv() { // do stuff } render() { return
} }
  • React 组件的内部方法命名不要使用下划线前缀。
// bad
React.createClass({
  _onClickSubmit() {
    // do stuff
  },

  // other stuff
});

// good
class extends React.Component {
  onClickSubmit() {
    // do stuff
  }

  // other stuff
}

排序

  • class extends React.Component 的顺序:
  1. static静态方法
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. 点击回调或者事件回调 比如 onClickSubmit() 或者 onChangeDescription()
  12. render函数中的 getter 方法 比如 getSelectReason() 或者 getFooterContent()
  13. 可选的 render 方法 比如 renderNavigation() 或者 renderProfilePicture()
  14. render
  • 怎样定义 propTypes, defaultProps, contextTypes
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 {this.props.text}
  }
}

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

export default Link;
  1. displayName
  2. propTypes
  3. contextTypes
  4. childContextTypes
  5. mixins
  6. statics
  7. defaultProps
  8. getDefaultProps
  9. getInitialState
  10. getChildContext
  11. componentWillMount
  12. componentDidMount
  13. componentWillReceiveProps
  14. shouldComponentUpdate
  15. componentWillUpdate
  16. componentDidUpdate
  17. componentWillUnmount
  18. clickHandlers or eventHandlers like onClickSubmit() or onChangeDescription()
  19. getter methods for render like getSelectReason() or getFooterContent()
  20. Optional render methods like renderNavigation() or renderProfilePicture()
  21. 点击回调或者事件回调 比如 onClickSubmit() 或者 onChangeDescription()
  22. render函数中的 getter 方法 比如 getSelectReason() 或者 getFooterContent()
  23. 可选的 render 方法 比如 renderNavigation() 或者 renderProfilePicture()
  24. render

isMounted

为什么这样做? isMounted是一种反模式,当使用 ES6 类风格声明 React 组件时该属性不可用,并且即将被官方弃用。