Airbnb React/JSX 編碼規范

Airbnb React/JSX 編碼規范

算是最合理的React/JSX編碼規范之一了

內容目錄

  1. 基本規范
  2. Class vs React.createClass vs stateless
  3. 命名
  4. 聲明模塊
  5. 代碼對齊
  6. 單引號還是雙引號
  7. 空格
  8. 屬性
  9. Refs引用
  10. 括號
  11. 標簽
  12. 函數/方法
  13. 模塊生命周期
  14. isMounted

Basic Rules 基本規范

  • 每個文件只寫一個模塊.
    • 但是多個無狀態模塊可以放在單個文件中. eslint:?react/no-multi-comp.
  • 推薦使用JSX語法.
  • 不要使用?React.createElement,除非從一個非JSX的文件中初始化你的app.

創建模塊

Class vs React.createClass vs stateless

  • 如果你的模塊有內部狀態或者是refs, 推薦使用?class extends React.Component?而不是?React.createClass?,除非你有充足的理由來使用這些方法.
    eslint:?react/prefer-es6-class?react/prefer-stateless-function

      // badconst Listing = React.createClass({
        // ...render() {
          return <div>{this.state.hello}</div>;}});  // goodclass Listing extends React.Component {
        // ...render() {
          return <div>{this.state.hello}</div>;}}

    如果你的模塊沒有狀態或是沒有引用refs, 推薦使用普通函數(非箭頭函數)而不是類:

      // badclass Listing extends React.Component {render() {
          return <div>{this.props.hello}</div>;}}  // bad (relying on function name inference is discouraged)const Listing = ({ hello }) => (<div>{hello}</div>);  // goodfunction Listing({ hello }) {
        return <div>{hello}</div>;}

Naming 命名

  • 擴展名: React模塊使用?.jsx?擴展名.
  • 文件名: 文件名使用駝峰式. 如,?ReservationCard.jsx.
  • 引用命名: React模塊名使用駝峰式命名,實例使用駱駝式命名. eslint:?react/jsx-pascal-case

    // badimport reservationCard from './ReservationCard';// goodimport ReservationCard from './ReservationCard';// badconst ReservationItem = <ReservationCard />;// goodconst reservationItem = <ReservationCard />;
  • 模塊命名: 模塊使用當前文件名一樣的名稱. 比如?ReservationCard.jsx?應該包含名為?ReservationCard的模塊. 但是,如果整個文件夾是一個模塊,使用?index.js作為入口文件,然后直接使用?index.js?或者文件夾名作為模塊的名稱:

    // badimport Footer from './Footer/Footer';// badimport Footer from './Footer/index';// goodimport Footer from './Footer';
  • 高階模塊命名: 對于生成一個新的模塊,其中的模塊名?displayName?應該為高階模塊名和傳入模塊名的組合. 例如, 高階模塊?withFoo(), 當傳入一個?Bar?模塊的時候, 生成的模塊名?displayName?應該為?withFoo(Bar).

    為什么?一個模塊的?displayName?可能會在開發者工具或者錯誤信息中使用到,因此有一個能清楚的表達這層關系的值能幫助我們更好的理解模塊發生了什么,更好的Debug.

      // bad  export default function withFoo(WrappedComponent) {
        return function WithFoo(props) {
          return <WrappedComponent {...props} foo />;}}  // good  export default function withFoo(WrappedComponent) {function WithFoo(props) {
          return <WrappedComponent {...props} foo />;}const wrappedComponentName = WrappedComponent.displayName      || WrappedComponent.name      || 'Component';WithFoo.displayName = `withFoo(${wrappedComponentName})`;
        return WithFoo;}
  • 屬性命名: 避免使用DOM相關的屬性來用作其他的用途。

    為什么?對于style?和?className這樣的屬性名,我們都會默認它們代表一些特殊的含義,如元素的樣式,CSS class的名稱。在你的應用中使用這些屬性來表示其他的含義會使你的代碼更難閱讀,更難維護,并且可能會引起bug。

      // bad<MyComponent style="fancy" />  // good<MyComponent variant="fancy" />

Declaration 聲明模塊

  • 不要使用?displayName?來命名React模塊,而是使用引用來命名模塊, 如 class 名稱.

    // badexport default React.createClass({
      displayName: 'ReservationCard',
      // stuff goes here
    });// goodexport default class ReservationCard extends React.Component {
    }

Alignment 代碼對齊

  • 遵循以下的JSX語法縮進/格式. eslint:?react/jsx-closing-bracket-location

    // bad
    <Foo superLongParam="bar"anotherSuperLongParam="baz" />// good, 有多行屬性的話, 新建一行關閉標簽
    <FoosuperLongParam="bar"anotherSuperLongParam="baz"
    />// 若能在一行中顯示, 直接寫成一行
    <Foo bar="bar" />// 子元素按照常規方式縮進
    <FoosuperLongParam="bar"anotherSuperLongParam="baz"
    ><Quux />
    </Foo>

Quotes 單引號還是雙引號

  • 對于JSX屬性值總是使用雙引號("), 其他均使用單引號. 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' }} />

Spacing 空格

  • 總是在自動關閉的標簽前加一個空格,正常情況下也不需要換行. eslint:?no-multi-spaces,?react/jsx-space-before-closing

    // bad
    <Foo/>// very bad
    <Foo                 />// bad
    <Foo/>// good
    <Foo />
  • 不要在JSX?{}?引用括號里兩邊加空格. eslint:?react/jsx-curly-spacing

    // bad
    <Foo bar={ baz } />// good
    <Foo bar={baz} />

Props 屬性

  • JSX屬性名使用駱駝式風格camelCase.

    // bad
    <FooUserName="hello"phone_number={12345678}
    />// good
    <FoouserName="hello"phoneNumber={12345678}
    />
  • 如果屬性值為?true, 可以直接省略. eslint:?react/jsx-boolean-value

    // bad
    <Foohidden={true}
    />// good
    <Foohidden
    />
  • <img>?標簽總是添加?alt?屬性. 如果圖片以presentation(感覺是以類似PPT方式顯示?)方式顯示,alt?可為空, 或者<img>?要包含role="presentation". eslint:?jsx-a11y/img-has-alt

    // bad
    <img src="hello.jpg" />// good
    <img src="hello.jpg" alt="Me waving hello" />// good
    <img src="hello.jpg" alt="" />// good
    <img src="hello.jpg" role="presentation" />
  • 不要在?alt?值里使用如 "image", "photo", or "picture"包括圖片含義這樣的詞, 中文也一樣. eslint:?jsx-a11y/img-redundant-alt

    為什么? 屏幕助讀器已經把?img?標簽標注為圖片了, 所以沒有必要再在?alt?里說明了.

      // bad<img src="hello.jpg" alt="Picture of me waving hello" />  // good<img src="hello.jpg" alt="Me waving hello" />
  • 使用有效正確的 aria?role屬性值?ARIA roles. eslint:?jsx-a11y/aria-role

    // bad - not an ARIA role
    <div role="datepicker" />// bad - abstract ARIA role
    <div role="range" />// good
    <div role="button" />
  • 不要在標簽上使用?accessKey?屬性. eslint:?jsx-a11y/no-access-key

    為什么? 屏幕助讀器在鍵盤快捷鍵與鍵盤命令時造成的不統一性會導致閱讀性更加復雜.

    // bad
    <div accessKey="h" />// good
    <div />
  • 避免使用數組的index來作為屬性key的值,推薦使用唯一ID. (為什么?)

    // bad
    {todos.map((todo, index) =><Todo{...todo}key={index}/>
    )}// good
    {todos.map(todo => (<Todo{...todo}key={todo.id}/>
    ))}

Refs

  • 總是在Refs里使用回調函數. eslint:?react/no-string-refs

    // bad
    <Fooref="myRef"
    />// good
    <Fooref={ref => { this.myRef = ref; }}
    />

Parentheses 括號

  • 將多行的JSX標簽寫在?()里. eslint:?react/wrap-multilines

    // badrender() {
      return <MyComponent className="long body" foo="bar"><MyChild /></MyComponent>;
    }// goodrender() {
      return (<MyComponent className="long body" foo="bar"><MyChild /></MyComponent>);
    }// good, 單行可以不需要render() {const body = <div>hello</div>;
      return <MyComponent>{body}</MyComponent>;
    }

Tags 標簽

  • 對于沒有子元素的標簽來說總是自己關閉標簽. eslint:?react/self-closing-comp

    // bad
    <Foo className="stuff"></Foo>// good
    <Foo className="stuff" />
  • 如果模塊有多行的屬性, 關閉標簽時新建一行. eslint:?react/jsx-closing-bracket-location

    // bad
    <Foobar="bar"baz="baz" />// good
    <Foobar="bar"baz="baz"
    />

Methods 函數

  • 使用箭頭函數來獲取本地變量.

    function ItemList(props) {
      return (<ul>{props.items.map((item, index) => (        <Item          key={item.key}          onClick={() => doSomethingWith(item.name, index)}        />      ))}</ul>);
    }
  • 當在?render()?里使用事件處理方法時,提前在構造函數里把?this?綁定上去. eslint:?react/jsx-no-bind

    為什么? 在每次?render?過程中, 再調用?bind?都會新建一個新的函數,浪費資源.

      // badclass extends React.Component {onClickDiv() {
          // do stuff}render() {
          return <div onClick={this.onClickDiv.bind(this)} />}}  // goodclass extends React.Component {constructor(props) {super(props);      this.onClickDiv = this.onClickDiv.bind(this);}onClickDiv() {
          // do stuff}render() {
          return <div onClick={this.onClickDiv} />}}
  • 在React模塊中,不要給所謂的私有函數添加?_?前綴,本質上它并不是私有的.

    為什么?_?下劃線前綴在某些語言中通常被用來表示私有變量或者函數。但是不像其他的一些語言,在JS中沒有原生支持所謂的私有變量,所有的變量函數都是共有的。盡管你的意圖是使它私有化,在之前加上下劃線并不會使這些變量私有化,并且所有的屬性(包括有下劃線前綴及沒有前綴的)都應該被視為是共有的。了解更多詳情請查看Issue#1024, 和?#490?。

      // badReact.createClass({_onClickSubmit() {
          // do stuff},    // other stuff});  // goodclass extends React.Component {onClickSubmit() {
          // do stuff}    // other stuff}
  • 在?render?方法中總是確保?return?返回值. eslint:?react/require-render-return

    // badrender() {(<div />);
    }// goodrender() {
      return (<div />);
    }

Ordering React 模塊生命周期

  • class extends React.Component?的生命周期函數:

  1. 可選的?static?方法
  2. constructor?構造函數
  3. getChildContext?獲取子元素內容
  4. componentWillMount?模塊渲染前
  5. componentDidMount?模塊渲染后
  6. componentWillReceiveProps?模塊將接受新的數據
  7. shouldComponentUpdate?判斷模塊需不需要重新渲染
  8. componentWillUpdate?上面的方法返回?true, 模塊將重新渲染
  9. componentDidUpdate?模塊渲染結束
  10. componentWillUnmount?模塊將從DOM中清除, 做一些清理任務
  11. 點擊回調或者事件處理器?如?onClickSubmit()?或?onChangeDescription()
  12. render?里的 getter 方法?如?getSelectReason()?或?getFooterContent()
  13. 可選的 render 方法?如?renderNavigation()?或?renderProfilePicture()
  14. render?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?的生命周期函數,與使用class稍有不同: eslint:?react/sort-comp

  1. displayName?設定模塊名稱
  2. propTypes?設置屬性的類型
  3. contextTypes?設置上下文類型
  4. childContextTypes?設置子元素上下文類型
  5. mixins?添加一些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. render

isMounted

  • 不要再使用?isMounted. eslint:?react/no-is-mounted

    為什么??isMounted?反人類設計模式:(), 在 ES6 classes 中無法使用, 官方將在未來的版本里刪除此方法.

? 回到頂部


來源:?https://github.com/JasonBoy/javascript/tree/master/react


來自為知筆記(Wiz)


轉載于:https://www.cnblogs.com/itlyh/p/6020648.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457033.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457033.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457033.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mysql數據庫使用總結

mysql數據庫使用總結 本文主要記錄一些mysql日常使用的命令&#xff0c;供以后查詢。 1.更改root密碼 mysqladmin -uroot password yourpassword 2.遠程登陸mysql服務器 mysql -uroot -p -h192.168.137.10 -P3306 3.查詢數據庫 show databases; 4.進入某個數據庫 use databa…

c語言遞歸漢諾塔次數,漢諾塔問題(C語言經典遞歸問題(一))

把A桿上的金盤全部移到C桿上&#xff0c;并仍保持原有順序疊好。操作規則&#xff1a;每次只能移動一個盤子&#xff0c;并且在移動過程中三根桿上都始終保持大盤在下&#xff0c;小盤在上&#xff0c;操作過程中盤子可以置于A、B、C任一桿上。思路&#xff1a;圖解&#xff1a…

Eclipes導入的項目中的中文都是亂碼的解決辦法

把項目導入Eclipse時&#xff0c;里邊的中文全是亂碼&#xff0c;試了很多方法&#xff0c;最終總結一下&#xff01; eclipse之所以會出現亂碼問題是因為eclipse編輯器選擇的編碼規則是可變的。一般默認都是UTF-8或者GBK&#xff0c;當從外部導入的一個工程時&#xff0c;如果…

理解瀏覽器是如何加載及渲染網頁的

先上圖&#xff0c;我們再慢慢解釋&#xff0c;這圖就是瀏覽器加載網頁的一個過程 當我們在瀏覽器輸入一個地址&#xff08;比如:http://toadw.cn&#xff09;,那么點擊回車后&#xff0c;瀏覽器是如何加載網頁的呢&#xff1f; 加載過程 一開始瀏覽器是不知道你輸入的http://t…

CentOS下的Mysql的安裝和使用

1.使用安裝命令 &#xff1a;yum -y install mysql mysql-server mysql-devel 安裝完成卻發現Myserver安裝缺失&#xff0c;在網上找原因&#xff0c;原來是因為CentOS 7上把MySQL從默認軟件列表中移除了&#xff0c;用MariaDB來代替&#xff0c;所以這導致我們必須要去官網上…

NOIP模擬題——神秘大門

【題目描述】最近小K大牛經過調查發現&#xff0c;在WZland的最南方——WZ Antarctica 出現了奇怪的磁場反應。為了弄清楚這一現象&#xff0c;小K 大牛親自出馬&#xff0c;來到了WZ Antarctica。小K大牛發現WZ Antarctica 出現了一道神秘的大門。人總有好奇心&#xff0c;小K…

大學c語言程序設計大賽,關于舉辦寧夏大學第二屆C語言程序設計大賽的通知

各學院&#xff1a;根據學校《關于進一步加強基礎課教學改革的意見》(寧大校發〔2008〕178號)、《關于加強學生創新精神和創新能力培養的實施意見》(寧大校發〔2008〕75號)的有關文件精神&#xff0c;經研究決定舉辦寧夏大學第二屆C語言程序設計大賽&#xff0c;從中選拔出優秀…

Android中創建自己的對話框

Activities提供了一種方便管理的創建、保存、回復的對話框機制&#xff0c;例如 onCreateDialog(int), onPrepareDialog(int, Dialog), showDialog(int), dismissDialog(int)等方法&#xff0c;如果使用這些方法的話&#xff0c;Activity將通過getOwnerActivity()方法返回該Act…

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11

搭建Django2.0Python3MySQL5時同步數據庫時報錯&#xff1a; django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None 解決辦法&#xff1a; 找到Python安裝路勁下的Python36-32\Lib\site-packages\django\db\backend…

一件很好笑的事情

我是一個比較習慣努力學習的人&#xff0c; 我也會去學習各種可能與我有交集的知識&#xff0c; 就在這幾天&#xff0c;我看到以前的一個android網絡培訓學校開辦了C/C的培訓&#xff0c;這是挺好的事&#xff0c; 但是看他們的文件&#xff0c;我就奇怪了。 這份文件&#xf…

c語言實現循環鏈表,c語言實現循環鏈表的基本操作

循環鏈表和單鏈表其實區別不大,差別僅在于算法中的循環條件不是p或者p->next,而是是否等于頭指針。下面這個例子簡單的實現了循環鏈表的基本操作,其中插入和刪除只是完成了主要的部分,沒有判斷。#include#includestruct Data{char name;int age;};struct CirList{Data *data…

關于Eclipes的Logcat無法打印消息的解決辦法

轉自&#xff1a;http://blog.csdn.net/harry211/article/details/8453532 調試程序需要打印一些消息出來&#xff0c;logcat不好用的話就很麻煩了。這個問題折騰了好久&#xff0c;為啥就是不出來呢&#xff1f; 上網找了很多解決辦法&#xff1a; 重啟eclipse 重啟adb 重啟…

17:文字排版

17:文字排版 查看提交統計提問總時間限制: 1000ms內存限制: 65536kB描述給一段英文短文&#xff0c;單詞之間以空格分隔&#xff08;每個單詞包括其前后緊鄰的標點符號&#xff09;。請將短文重新排版&#xff0c;要求如下&#xff1a; 每行不超過80個字符&#xff1b;每個單詞…

解決AttributeError: 'str' object has no attribute 'decode'報錯問題

順著報錯文件點進去&#xff0c;找到query query.decode(errors‘replace’) 將decode修改為encode即可

c語言指針數組課件,C語言指針與數組教程課件.ppt

C語言指針與數組教程;教學要求;本章主要內容;引子;#include void swap ( int x, int y ) { printf("調用時&#xff1a;x地址為&#xff1a;%p, 值為&#xff1a;%d\n",&x,x); printf("調用時&#xff1a;y地址為&#xff1a;%p, 值為&#xff1a;%d\n"…

Android控制EditText的焦點

在項目中&#xff0c;一進入一個頁面, EditText默認就會自動獲取焦點。 那么如何取消這個默認行為呢&#xff1f; 在網上找了好久&#xff0c;有點 監聽軟鍵盤事件&#xff0c;有點 調用 clearFouse()方法&#xff0c;但是測試了都沒有&#xff01; xml中也找不到相應的屬性可以…

解決python中html 代碼被注釋掉 依舊被解釋導致報錯ERROR:tornado.access:500 GET /home (xxx.xxx.xxx.xxx)

ERROR:tornado.access:500 GET /home (xxx.xxx.xxx.xxx) 注釋的是Html代碼&#xff0c;是給瀏覽器看的。 Html里的代碼還是要執行。注釋python代碼用{# #}

springMvc 傳子 bean 中有bean

2019獨角獸企業重金招聘Python工程師標準>>> bean 類型 如下 1. json 字符串 $.ajax({ url :${ctx}/test/testData/f1?bookjava, type: post, dataType : "json", con…

通過rsync搭建一個遠程備份系統(二)

Rsyncinotify實時備份數據 rsync在同步數據的時候&#xff0c;需要掃描所有文件后進行對比&#xff0c;然后進行差量傳輸&#xff0c;如果文件達到了百萬或者千萬級別以上是&#xff0c;掃描文件的時間也很長&#xff0c;而如果只有少量的文件變更了&#xff0c;那么此時rsync是…

C語言掃地雷游戲的題目簡介,C語言程序設計課程設計(論文)-掃地雷游戲.doc...

C語言程序設計課程設計(論文)-掃地雷游戲遼 寧 工 業 大 學C語言程序設計 課程設計(論文)題目&#xff1a; 掃地雷游戲院(系)&#xff1a; 軟件學院專業班級: 電子商務091班學 號:學生姓名&#xff1a;指導教師&#xff1a;教師職稱&#xff1a; 助 教起止時間&#xff1a;2009…