React代碼開發規範

前言

通常在團隊開發中每一個人的代碼習慣都不太同樣,這樣就會致使代碼風格不一致,以至於維護和修改bug的時候看別人的代碼成爲一種痛苦...
這種狀況尤爲在前端開發中尤其明顯。由於關於前端的開發規範貌似也沒有行業權威標準。這幾天在網上看了下,基本上在開發中經過eslint進行約束,airbnb的標準貌似頗爲推崇,今天稍微整理下,準備在往後開發中造成習慣。javascript

基本規則

  1. 每一個文件只包含一個React組件。eslint: react/no-multi-comp;(官方表示在無狀態,或者Pure組件容許一個文件包含多個組件,可是我我的以爲一個文件只包含一個組件比較淺顯易懂)
  2. 始終使用JSX語法;
  3. 不要始終React.createElement方法,除非初始化app的文件不是JSX格式;

Class vs React.createClass vs stateless

  1. 若是組件擁有內部的state或者refs時,更推薦使用class extends Component,除非有更好的理由使用mixin。eslint:react/prefer-es6-class
// bad
const Listing = React.createClass({
  // ...
  render() {
    return <div>{this.state.hello}</div>;
  }
});

// good
class Listing extends React.Component {
  // ...
  render() {
    return <div>{this.state.hello}</div>;
  }
}

若是組件沒有擁有內部的state或者refs,那麼普通函數(不要使用箭頭函數)比類的寫法更好:前端

// bad
class Listing extends React.Component {
  render() {
    return <div>{this.props.hello}</div>;
  }
}

// bad (由於箭頭函數沒有「name」屬性)
const Listing = ({ hello }) => (
  <div>{hello}</div>
);

// good
function Listing({ hello }) {
  return <div>{hello}</div>;
}

命名

  1. 拓展名:React組件使用.jsx擴展名;
  2. 文件名:文件名使用帕斯卡命名:HomePage.jsx
  3. 引用命名:React組件使用帕斯卡命名,引用實例採用駝峯式命名:eslint: react/jsx-pascal-case)(我的不喜歡這樣,引用命名仍是按照帕斯卡命名)
// bad
import reservationCard from './ReservationCard';

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

// bad
const ReservationItem = <ReservationCard />;

// good
const reservationItem = <ReservationCard />;

聲明

不要使用displayName屬性來命名組件,應該使用類的引用名稱。java

// bad
export default React.createClass({
  displayName: 'ReservationCard',
  // stuff goes here
});

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

對齊

爲JSX語法使用下列的對齊方式:eslint: react/jsx-closing-bracket-locationreact

// bad
<Foo superLongParam="bar"
     anotherSuperLongParam="baz" />

// good
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
/>

// 若是組件的屬性能夠放在一行就保持在當前一行中,(我的以爲若是隻有一個屬性就放在一行)
<Foo bar="bar" />

// 多行屬性採用縮進
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
>
  <Quux />
</Foo>

引號

JSX的屬性都採用雙引號,其餘的JS都使用單引號:jsx-quotes
爲何這樣作?JSX 屬性 不能包含轉義的引號, 因此當輸入"don't"這類的縮寫的時候用雙引號會更方便。es6

// bad
<Foo bar='bar' />

// good
<Foo bar="bar" />

// bad
<Foo style={{ left: "20px" }} />

// good
<Foo style={{ left: '20px' }} />

空格

始終在自閉和標籤前添加一個空格。app

// bad
<Foo/>

// very bad
<Foo                 />

// bad
<Foo
 />

// good
<Foo />

屬性

  1. 屬性名稱始終使用駝峯命名法。
// bad
<Foo
  UserName="hello"
  phone_number={12345678}
/>

// good
<Foo
  userName="hello"
  phoneNumber={12345678}
/>
  1. 當屬性值等於true的時候,省略該屬性的賦值。eslint:react/jsx-boolean-value
// bad
<Foo
  hidden={true}
/>

// good
<Foo
  hidden
/>

括號

使用括號包裹多行JSX標籤,react/wrap-multilinesless

// bad
render() {
  return <MyComponent className="long body" foo="bar">
           <MyChild />
         </MyComponent>;
}

// good
render() {
  return (
    <MyComponent className="long body" foo="bar">
      <MyChild />
    </MyComponent>
  );
}

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

標籤

  1. 當標籤沒有子元素的時候,始終使用自閉合的標籤:eslint: react/self-closing-comp
// bad
<Foo className="stuff"></Foo>

// good
<Foo className="stuff" />
  1. 若是控件有多行屬性,關閉標籤要另起一行。 eslint: react/jsx-closing-bracket-location
// bad
<Foo
  bar="bar"
  baz="baz" />

// good
<Foo
  bar="bar"
  baz="baz"
/>

方法

在 render 方法中事件的回調函數,應該在構造函數中進行bind綁定。 eslint: react/jsx-no-bind
爲何這樣作? 在 render 方法中的 bind 調用每次調用 render 的時候都會建立一個全新的函數。函數

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

  render() {
    return <div onClick={this.onClickDiv.bind(this)} />
  }
}

// good
class extends React.Component {
  constructor(props) {
    super(props);

    this.onClickDiv = this.onClickDiv.bind(this);
  }

  onClickDiv() {
    // do stuff
  }

  render() {
    return <div onClick={this.onClickDiv} />
  }
}
  1. React 組件的內部方法命名不要使用下劃線前綴。
// bad
React.createClass({
  _onClickSubmit() {
    // do stuff
  },

  // other stuff
});

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

  // other stuff
}

排序

class extends React.Component的順序:ui

  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()

可選的 render 方法 好比 renderNavigation() 或者 renderProfilePicture()this

  1. 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 <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
  }
}

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

export default Link;

關於這個開發規範差很少就這樣吧,eslint的配置我的在研究下,下次再放出來

相關文章
相關標籤/搜索