React代碼開發規范


前言

一般在團隊開發中每個人的代碼習慣都不太一樣,這樣就會導致代碼風格不一致,以致於維護和修改bug的時候看別人的代碼成為一種痛苦...
這種情況尤其在前端開發中尤為明顯。因為關於前端的開發規范貌似也沒有行業權威標准。這幾天在網上看了下,基本上在開發中通過eslint進行約束,airbnb的標准貌似頗為推崇,今天稍微整理下,准備在日后開發中形成習慣。

基本規則

  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屬性來命名組件,應該使用類的引用名稱。


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

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

對齊

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


// 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"這類的縮寫的時候用雙引號會更方便。


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

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

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

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

空格

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


// 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-multilines


// 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的順序:

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

  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 &lt;a href={this.props.url} 關於這個開發規范差不多就這樣吧,eslint的配置個人在研究下,下次再放出來</p>

來源:https://segmentfault.com/a/1190000017263310


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM