javascript
Airbnb React/JSX 编码规范
Airbnb React/JSX 編碼規(guī)范
算是最合理的React/JSX編碼規(guī)范之一了
內(nèi)容目錄
Basic Rules 基本規(guī)范
- 每個(gè)文件只寫一個(gè)模塊.
- 但是多個(gè)無狀態(tài)模塊可以放在單個(gè)文件中. eslint:?react/no-multi-comp.
- 推薦使用JSX語法.
- 不要使用?React.createElement,除非從一個(gè)非JSX的文件中初始化你的app.
創(chuàng)建模塊
Class vs React.createClass vs stateless
如果你的模塊有內(nèi)部狀態(tài)或者是refs, 推薦使用?class extends React.Component?而不是?React.createClass?,除非你有充足的理由來使用這些方法.
// badconst Listing = React.createClass({ // ...render() { return <div>{this.state.hello}</div>;}}); // goodclass Listing extends React.Component { // ...render() { return <div>{this.state.hello}</div>;}}
eslint:?react/prefer-es6-class?react/prefer-stateless-function如果你的模塊沒有狀態(tài)或是沒有引用refs, 推薦使用普通函數(shù)(非箭頭函數(shù))而不是類:
// 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 命名
- 擴(kuò)展名: React模塊使用?.jsx?擴(kuò)展名.
- 文件名: 文件名使用駝峰式. 如,?ReservationCard.jsx.
引用命名: React模塊名使用駝峰式命名,實(shí)例使用駱駝式命名. eslint:?react/jsx-pascal-case
// badimport reservationCard from './ReservationCard';// goodimport ReservationCard from './ReservationCard';// badconst ReservationItem = <ReservationCard />;// goodconst reservationItem = <ReservationCard />;模塊命名: 模塊使用當(dāng)前文件名一樣的名稱. 比如?ReservationCard.jsx?應(yīng)該包含名為?ReservationCard的模塊. 但是,如果整個(gè)文件夾是一個(gè)模塊,使用?index.js作為入口文件,然后直接使用?index.js?或者文件夾名作為模塊的名稱:
// badimport Footer from './Footer/Footer';// badimport Footer from './Footer/index';// goodimport Footer from './Footer';高階模塊命名: 對(duì)于生成一個(gè)新的模塊,其中的模塊名?displayName?應(yīng)該為高階模塊名和傳入模塊名的組合. 例如, 高階模塊?withFoo(), 當(dāng)傳入一個(gè)?Bar?模塊的時(shí)候, 生成的模塊名?displayName?應(yīng)該為?withFoo(Bar).
為什么?一個(gè)模塊的?displayName?可能會(huì)在開發(fā)者工具或者錯(cuò)誤信息中使用到,因此有一個(gè)能清楚的表達(dá)這層關(guān)系的值能幫助我們更好的理解模塊發(fā)生了什么,更好的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相關(guān)的屬性來用作其他的用途。
為什么?對(duì)于style?和?className這樣的屬性名,我們都會(huì)默認(rèn)它們代表一些特殊的含義,如元素的樣式,CSS class的名稱。在你的應(yīng)用中使用這些屬性來表示其他的含義會(huì)使你的代碼更難閱讀,更難維護(hù),并且可能會(huì)引起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 代碼對(duì)齊
遵循以下的JSX語法縮進(jìn)/格式. eslint:?react/jsx-closing-bracket-location
// bad <Foo superLongParam="bar"anotherSuperLongParam="baz" />// good, 有多行屬性的話, 新建一行關(guān)閉標(biāo)簽 <FoosuperLongParam="bar"anotherSuperLongParam="baz" />// 若能在一行中顯示, 直接寫成一行 <Foo bar="bar" />// 子元素按照常規(guī)方式縮進(jìn) <FoosuperLongParam="bar"anotherSuperLongParam="baz" ><Quux /> </Foo>
Quotes 單引號(hào)還是雙引號(hào)
對(duì)于JSX屬性值總是使用雙引號(hào)("), 其他均使用單引號(hào). eslint:?jsx-quotes
為什么? JSX屬性?不能包括轉(zhuǎn)譯的引號(hào), 因此在雙引號(hào)里包括像?"don't"?的屬性值更容易輸入. HTML屬性也是用雙引號(hào),所以JSX屬性也遵循同樣的語法.
// bad<Foo bar='bar' /> // good<Foo bar="bar" /> // bad<Foo style={{ left: "20px" }} /> // good<Foo style={{ left: '20px' }} />
Spacing 空格
總是在自動(dòng)關(guān)閉的標(biāo)簽前加一個(gè)空格,正常情況下也不需要換行. eslint:?no-multi-spaces,?react/jsx-space-before-closing
// bad <Foo/>// very bad <Foo />// bad <Foo/>// good <Foo />不要在JSX?{}?引用括號(hào)里兩邊加空格. eslint:?react/jsx-curly-spacing
// bad <Foo bar={ baz } />// good <Foo bar={baz} />
Props 屬性
JSX屬性名使用駱駝式風(fēng)格camelCase.
// bad <FooUserName="hello"phone_number={12345678} />// good <FoouserName="hello"phoneNumber={12345678} />如果屬性值為?true, 可以直接省略. eslint:?react/jsx-boolean-value
// bad <Foohidden={true} />// good <Foohidden /><img>?標(biāo)簽總是添加?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
為什么? 屏幕助讀器已經(jīng)把?img?標(biāo)簽標(biāo)注為圖片了, 所以沒有必要再在?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" />不要在標(biāo)簽上使用?accessKey?屬性. eslint:?jsx-a11y/no-access-key
為什么? 屏幕助讀器在鍵盤快捷鍵與鍵盤命令時(shí)造成的不統(tǒng)一性會(huì)導(dǎo)致閱讀性更加復(fù)雜.
// bad <div accessKey="h" />// good <div />避免使用數(shù)組的index來作為屬性key的值,推薦使用唯一ID. (為什么?)
// bad {todos.map((todo, index) =><Todo{...todo}key={index}/> )}// good {todos.map(todo => (<Todo{...todo}key={todo.id}/> ))}
Refs
總是在Refs里使用回調(diào)函數(shù). eslint:?react/no-string-refs
// bad <Fooref="myRef" />// good <Fooref={ref => { this.myRef = ref; }} />
Parentheses 括號(hào)
將多行的JSX標(biāo)簽寫在?()里. 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 標(biāo)簽
對(duì)于沒有子元素的標(biāo)簽來說總是自己關(guān)閉標(biāo)簽. eslint:?react/self-closing-comp
// bad <Foo className="stuff"></Foo>// good <Foo className="stuff" />如果模塊有多行的屬性, 關(guān)閉標(biāo)簽時(shí)新建一行. eslint:?react/jsx-closing-bracket-location
// bad <Foobar="bar"baz="baz" />// good <Foobar="bar"baz="baz" />
Methods 函數(shù)
使用箭頭函數(shù)來獲取本地變量.
function ItemList(props) { return (<ul>{props.items.map((item, index) => ( <Item key={item.key} onClick={() => doSomethingWith(item.name, index)} /> ))}</ul>); }當(dāng)在?render()?里使用事件處理方法時(shí),提前在構(gòu)造函數(shù)里把?this?綁定上去. eslint:?react/jsx-no-bind
為什么? 在每次?render?過程中, 再調(diào)用?bind?都會(huì)新建一個(gè)新的函數(shù),浪費(fèi)資源.
// 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模塊中,不要給所謂的私有函數(shù)添加?_?前綴,本質(zhì)上它并不是私有的.
為什么?_?下劃線前綴在某些語言中通常被用來表示私有變量或者函數(shù)。但是不像其他的一些語言,在JS中沒有原生支持所謂的私有變量,所有的變量函數(shù)都是共有的。盡管你的意圖是使它私有化,在之前加上下劃線并不會(huì)使這些變量私有化,并且所有的屬性(包括有下劃線前綴及沒有前綴的)都應(yīng)該被視為是共有的。了解更多詳情請查看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?的生命周期函數(shù):
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?的生命周期函數(shù),與使用class稍有不同: eslint:?react/sort-comp
isMounted
不要再使用?isMounted. eslint:?react/no-is-mounted
為什么??isMounted?反人類設(shè)計(jì)模式:(), 在 ES6 classes 中無法使用, 官方將在未來的版本里刪除此方法.
? 回到頂部
來源:?https://github.com/JasonBoy/javascript/tree/master/react
來自為知筆記(Wiz)
轉(zhuǎn)載于:https://www.cnblogs.com/itlyh/p/6020648.html
總結(jié)
以上是生活随笔為你收集整理的Airbnb React/JSX 编码规范的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: #100. 矩阵乘法
- 下一篇: JavaScript学习笔记(四)——j