【轉】Airbnb React編碼規范


Airbnb的編碼規范是在業界非常流行的一套規范,而且它一直都在進化,推出最新技術的規范

用更合理的方式書寫React和JSX

基本規則

  • 每個文件只包含一個React組件;
  • 始終使用 JSX 語法;
  • 不要使用 React.createElement方法,除非初始化 app 的文件不是 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 <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>;
    }

     

命名

  • 擴展名:React 組件使用.jsx擴展名;
  • 文件名:文件名使用帕斯卡命名。 例如: ReservationCard.jsx。
  • 引用命名:React 組件使用帕斯卡命名,引用實例采用駝峰命名。 eslint: react/jsx-pascal-case


    // bad
    import reservationCard from './ReservationCard';
    
    // good
    import ReservationCard from './ReservationCard';
    
    // bad
    const ReservationItem = <ReservationCard />;
    
    // good
    const reservationItem = <ReservationCard />;
    

      

  • 組件命名:組件名稱應該和文件名一致, 例如: 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 {
    }

     

對齊

  • 為 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 都使用單引號。eslint: jsx-quotes

    為什么這樣做?JSX 屬性 不能包含轉義的引號, 所以當輸入"don't"這類的縮寫的時候用雙引號會更方便。

    標准的 HTML 屬性通常也會使用雙引號,所以 JSX 屬性也會遵守這樣的約定。

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

     

屬性

  • 屬性名稱始終使用駝峰命名法。


    // bad
    <Foo
      UserName="hello"
      phone_number={12345678}
    />
    
    // good
    <Foo
      userName="hello"
      phoneNumber={12345678}
    />

     

  • 當屬性值等於true的時候,省略該屬性的賦值。 eslint: react/jsx-boolean-value


    // bad
    <Foo
      hidden={true}
    />
    
    // good
    <Foo
      hidden
    />

     

括號

  • 用括號包裹多行 JSX 標簽。 eslint: 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>;
    }

     

標簽

  • 當標簽沒有子元素時,始終時候自閉合標簽。 eslint: react/self-closing-comp


    // bad
    <Foo className="stuff"></Foo>
    
    // good
    <Foo className="stuff" />

     

  • 如果控件有多行屬性,關閉標簽要另起一行。 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} />
        }
      }

     

  • 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 <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
      }
    }
    
    Link.propTypes = propTypes;
    Link.defaultProps = defaultProps;
    
    export default Link;

     

  • React.createClass的排序:eslint: react/sort-comp

  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. 點擊回調或者事件回調 比如 onClickSubmit() 或者 onChangeDescription()
  19. render函數中的 getter 方法 比如 getSelectReason() 或者 getFooterContent()
  20. 可選的 render 方法 比如 renderNavigation() 或者 renderProfilePicture()
  21. render

isMounted


擴展


免責聲明!

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



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