標籤:
Airbnb的編碼規範是在業界非常流行的一套規範,而且它一直都在進化,推出最新技術的規範
原文:https://zhuanlan.zhihu.com/p/20616464
用更合理的方式書寫React和JSX
基本規則
- 每個檔案只包含一個React組件;
- 但是無狀態, 或者 Pure 組件 允許一個檔案包含多個組件。eslint: react/no-multi-comp.
- 始終使用 JSX 文法;
- 不要使用 React.createElement方法,除非初始化 app 的檔案不是 JSX 格式。
Class vs React.createClass vs stateless
如果組件擁有內部的 state 或者 refs 的時,更推薦使用 class extends React.Component,除非你有一個非常好的理由要使用 mixin。 eslint: react/prefer-es6-class
// badconst Listing = React.createClass({ // ... render() { return <div>{this.state.hello}</div>; }});// goodclass Listing extends React.Component { // ... render() { return <div>{this.state.hello}</div>; }}
如果沒有組件沒有內部 state 或者 refs,那麼普通函數 (不要使用箭頭函數) 比類的寫法更好:
// badclass Listing extends React.Component { render() { return <div>{this.props.hello}</div>; }}// bad (因為箭頭函數沒有“name”屬性)const Listing = ({ hello }) => ( <div>{hello}</div>);// goodfunction Listing({ hello }) { return <div>{hello}</div>;}
命名
- 副檔名: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.jsx 作為檔案名稱 並且使用檔案夾名稱作為組件名:
// badimport Footer from ‘./Footer/Footer‘;// badimport Footer from ‘./Footer/index‘;// goodimport Footer from ‘./Footer‘;
聲明
不要使用`displayName`屬性來命名組件,應該使用類的引用名稱。
// badexport default React.createClass({ displayName: ‘ReservationCard‘, // stuff goes here});// goodexport 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>
引號
空格
屬性
屬性名稱始終使用駝峰命名法。
// 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
// badrender() { return <MyComponent className="long body" foo="bar"> <MyChild /> </MyComponent>;}// goodrender() { return ( <MyComponent className="long body" foo="bar"> <MyChild /> </MyComponent> );}// good, when single linerender() { 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 組件的內部方法命名不要使用底線首碼。
// badReact.createClass({ _onClickSubmit() { // do stuff }, // other stuff});// goodclass extends React.Component { onClickSubmit() { // do stuff } // other stuff}
排序
- static靜態方法
- constructor
- getChildContext
- componentWillMount
- componentDidMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
- 點擊回調或者事件回調 比如 onClickSubmit() 或者 onChangeDescription()
- render函數中的 getter 方法 比如 getSelectReason() 或者 getFooterContent()
- 可選的 render 方法 比如 renderNavigation() 或者 renderProfilePicture()
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
- displayName
- propTypes
- contextTypes
- childContextTypes
- mixins
- statics
- defaultProps
- getDefaultProps
- getInitialState
- getChildContext
- componentWillMount
- componentDidMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
- 點擊回調或者事件回調 比如 onClickSubmit() 或者 onChangeDescription()
- render函數中的 getter 方法 比如 getSelectReason() 或者 getFooterContent()
- 可選的 render 方法 比如 renderNavigation() 或者 renderProfilePicture()
- render
isMounted
擴充
- 上訴的規則,你可用通過eslint的react外掛程式來完成配置:eslint-plugin-react ,javascript/packages/eslint-config-airbnb at master · airbnb/javascript · GitHub
- Fork了一個官方的repo,把規範翻譯在這裡,不僅有react的,還有兩個很火的翻譯版的ES5和ES6規則,強烈推薦沒有讀過的人讀一下,對你瞭解ES6也是非常好的途徑。GitHub - vikingmute/javascript: JavaScript Style Guide
【轉】Airbnb React編碼規範