React-Native開發(fā)規(guī)范
標(biāo)簽(空格分隔): React-Native JavaScript
一、編程規(guī)約
(一) 命名規(guī)約
-
【強(qiáng)制】 代碼中命名均不能以下劃線或美元符號(hào)開始,也不能以下劃線或美元符號(hào)結(jié)束;
`_name / $Object / name_ / name$ / Object$` -
【強(qiáng)制】 代碼中命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式; 說(shuō)明:正確的英文拼寫和語(yǔ)法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式 也要避免采用;
`反例: DaZhePromotion [打折] / getPingfenByName() [評(píng)分] / int 某變量 = 3` 【強(qiáng)制】類名使用 UpperCamelCase 風(fēng)格,必須遵從駝峰形式,第一個(gè)字母必須大寫;
LoginPage/MsgPage-
【強(qiáng)制】方法名、參數(shù)名、成員變量、局部變量都統(tǒng)一使用 lowerCamelCase風(fēng)格,必須遵從駝峰形式,第一個(gè)字母必須小寫;
localValue / getHttpMessage() / inputUserId 【強(qiáng)制】常量命名全部大寫,單詞間用下劃線隔開,力求語(yǔ)義表達(dá)完整清楚,不要嫌名字長(zhǎng);
正例: MAX_STOCK_COUNT 反例: MAX_COUNT【強(qiáng)制】使用抽象單詞命名類名或者變量時(shí),需加以修飾;
userMsg 等價(jià)于 userMessaage, userPic 等價(jià)于 userPicture【強(qiáng)制】中括號(hào)是數(shù)組類型的一部分,數(shù)組定義如下:String[] args;
反例:請(qǐng)勿使用String args[]的方式來(lái)定義。【強(qiáng)制】包名統(tǒng)一使用小寫,點(diǎn)分隔符之間有且僅有一個(gè)自然語(yǔ)義的英語(yǔ)單詞。包名統(tǒng)一使用單數(shù)形式,但是類名如果有復(fù)數(shù)含義,類名可以使用復(fù)數(shù)形式;
正例: 應(yīng)用工具類包名為com.fcs.open.util、類名為UrlUtils
-
【強(qiáng)制】文件夾命名統(tǒng)一小寫; 組件,或者類名,首字母全部大寫,遵守駝峰命名法;
img 存放圖片 app APP一些component artcomponent 一些art組件
(二) 常量定義
- 【強(qiáng)制】不允許出現(xiàn)任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中;
- 【推薦】不要使用一個(gè)常量類維護(hù)所有常量,應(yīng)該按常量功能進(jìn)行歸類,分開維護(hù)。
如:緩存相關(guān)的常量放在類:CacheConsts下;
系統(tǒng)配置相關(guān)的常量放在類:ConfigConsts下; 說(shuō)明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利于理解和維護(hù);
(三) 格式規(guī)約
- 【強(qiáng)制】大括號(hào)的使用約定。如果是大括號(hào)內(nèi)為空,則簡(jiǎn)潔地寫成{}即可,不需要換行;如果 是非空代碼塊則:
- 左大括號(hào)前不換行;
- 左大括號(hào)后換行;
- 右大括號(hào)前換行;
- 右大括號(hào)后還有else等代碼則不換行‘;’表示終止右大括號(hào)后必須換行。
- 【強(qiáng)制】 左括號(hào)和后一個(gè)字符之間不出現(xiàn)空格;同樣,右括號(hào)和前一個(gè)字符之間也不出現(xiàn)空格;
- 【強(qiáng)制】if/for/while/switch/do 等保留字與左右括號(hào)之間都必須加空格;
- 【強(qiáng)制】任何運(yùn)算符左右必須加一個(gè)空格;
說(shuō)明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號(hào)、三目運(yùn)行符等; - 【強(qiáng)制】縮進(jìn)采用 4 個(gè)空格,禁止使用 tab 字符;
- 【強(qiáng)制】單行字符數(shù)限制不超過(guò)120個(gè),超出需要換行,換行時(shí)遵循如下原則:
第二行相對(duì)第一行縮進(jìn)4個(gè)空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例;
運(yùn)算符與下文一起換行;
方法調(diào)用的點(diǎn)符號(hào)與下文一起換行;
-
在多個(gè)參數(shù)超長(zhǎng),逗號(hào)后進(jìn)行換行;
const path = Path() .moveTo(0, -radius/2) .arc(0, radius, 1) .arc(0, -radius, 1) .close();
-
【強(qiáng)制】方法參數(shù)在定義和傳入時(shí),多個(gè)參數(shù)逗號(hào)后邊必須加空格;
onMsgByCallAndMsg=(msg, title, type)=>{ this.setState({ callMsgAndMsg:msg }) } 【推薦】方法體內(nèi)的執(zhí)行語(yǔ)句組、變量的定義語(yǔ)句組、不同的業(yè)務(wù)邏輯之間或者不同的語(yǔ)義之間插入一個(gè)空行。相同業(yè)務(wù)邏輯和語(yǔ)義之間不需要插入空行。
說(shuō)明:沒(méi)有必要插入多行空格進(jìn)行隔開。【推薦】使用webStorm時(shí),導(dǎo)入附件的hoop-settings-1.0.jar文件,可統(tǒng)一格式化。
(四) package.json
【強(qiáng)制】在使用npm或者yarn獲取資源時(shí),必須在命令末尾添加--save;
說(shuō)明:使用此命令會(huì)把使用的第三方相關(guān)信息寫入到package.json,這樣,其他成員在下載或者更新代碼后使用npm i,就可以下載最新的npm,若不加 —save ,執(zhí)行npm i的時(shí)候不會(huì)下載,其他成員運(yùn)行項(xiàng)目后在運(yùn)行可能會(huì)報(bào)錯(cuò),此時(shí)需要分析查看報(bào)錯(cuò)信息進(jìn)行重新的npm install XX;【推薦】使用git或者svn進(jìn)行代碼版本管理時(shí),盡量不上傳node_module文件;
說(shuō)明:使用package.json進(jìn)行包管理,下載或更新代碼后,只需要執(zhí)行npm i;當(dāng)有修改npm包,建議進(jìn)行版本管理,上傳到私有的github倉(cāng)庫(kù)。【強(qiáng)制】使用第三方或拉取新倉(cāng)庫(kù)時(shí),第一步使用npm i或者npm install;
說(shuō)明:檢查版本是否存在沖突【推薦】在使用npm或者yarn獲取資源時(shí),推薦不在命令后添加 -g;
說(shuō)明,此命令可以讓此資源包在根目錄進(jìn)行獲取,不利于資源管理;【強(qiáng)制】當(dāng)升級(jí)或降級(jí)react-native版本時(shí),必須進(jìn)行代碼備份;
說(shuō)明:升級(jí)失敗或者涉及到原生代碼時(shí),可以進(jìn)行代碼回滾【強(qiáng)制】每個(gè)項(xiàng)目必須配置一個(gè)readMe文件,內(nèi)容包括測(cè)試,正式環(huán)境等相關(guān)配置文件以及注意事項(xiàng);
【推薦】安裝npm包是,推薦~來(lái)標(biāo)記版本號(hào);
說(shuō)明:和^的作用和區(qū)別:會(huì)匹配最近的小版本依賴包,比如~1.2.3會(huì)匹配所有1.2.x版本,但是不包括1.3.0
會(huì)匹配最新的大版本依賴包,比如1.2.3會(huì)匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0。那么該如何選擇呢?當(dāng)然你可以指定特定的版本號(hào),直接寫1.2.3,前面什么前綴都沒(méi)有,這樣固然沒(méi)問(wèn)題,但是如果依賴包發(fā)布新版本修復(fù)了一些小bug,那么需要手動(dòng)修改package.json文件;和^則可以解決這個(gè)問(wèn)題。但是需要注意^版本更新可能比較大,會(huì)造成項(xiàng)目代碼錯(cuò)誤,舊版本可能和新版本存在部分代碼不兼容。所以推薦使用來(lái)標(biāo)記版本號(hào),這樣可以保證項(xiàng)目不會(huì)出現(xiàn)大的問(wèn)題,也能保證包中的小bug可以得到修復(fù)。
(五) 控制語(yǔ)句
【強(qiáng)制】在一個(gè) switch 塊內(nèi),每個(gè)case要么通過(guò) break/return 等來(lái)終止,要么注釋說(shuō)明程序?qū)⒗^續(xù)執(zhí)行到哪一個(gè) case 為止;在一個(gè) switch 塊內(nèi),都必須包含一個(gè)default 語(yǔ)句并且 放在最后,即使它什么代碼也沒(méi)有。
【強(qiáng)制】在 if/else/for/while/do 語(yǔ)句中必須使用大括號(hào),即使只有一行代碼,避免使用 下面的形式:
if (condition) statements;-
【推薦】推薦盡量少用 else, if-else 的方式可以改寫成:
if(condition){ ... return obj; }
// 接著寫 else 的業(yè)務(wù)邏輯代碼;
說(shuō)明:如果非得使用
if()
...
else if(
)...else...
方式表達(dá)邏輯,【強(qiáng)制】請(qǐng)勿超過(guò)3層,
超過(guò)請(qǐng)使用狀態(tài)設(shè)計(jì)模式。
正例:邏輯上超過(guò) 3 層的 if-else 代碼可以使用衛(wèi)語(yǔ)句,或者狀態(tài)模式來(lái)實(shí)現(xiàn)。
4.【推薦】使用三目運(yùn)算,替換if else結(jié)構(gòu),精簡(jiǎn)代碼
let account=5;
if(account>10){
console.log("true");
}else {
console.log("false");
}
let msg=account>10?"true":"false";
5.【推薦】除常用方法(如 getXxx/isXxx)等外,不要在條件判斷中執(zhí)行其它復(fù)雜的語(yǔ)句,將復(fù) 雜邏輯判斷的結(jié)果賦值給一個(gè)有意義的布爾變量名,以提高可讀性。
說(shuō)明:很多 if 語(yǔ)句內(nèi)的邏輯相當(dāng)復(fù)雜,閱讀者需要分析條件表達(dá)式的最終結(jié)果,才能明確什么 樣的條件執(zhí)行什么樣的語(yǔ)句,那么,如果閱讀者分析邏輯表達(dá)式錯(cuò)誤呢?
//偽代碼如下
boolean existed = (file.open(fileName, "w") != null)&& (...) || (...);
if (existed) {
...
}
(六) 注釋規(guī)約
【強(qiáng)制】類、類屬性、類方法的注釋必須使用 Javadoc 規(guī)范,使用/*內(nèi)容/格式,不得使用 //xxx 方式;
說(shuō)明:在 IDE 編輯窗口中,Javadoc 方式會(huì)提示相關(guān)注釋,生成 Javadoc 可以正確輸出相應(yīng)注釋;在 IDE 中,工程調(diào)用方法時(shí),不進(jìn)入方法即可懸浮提示方法、參數(shù)、返回值的意義,提高閱讀效率。【強(qiáng)制】所有的類都必須添加創(chuàng)建者信息,以及類的說(shuō)明;
【強(qiáng)制】方法內(nèi)部單行注釋,在被注釋語(yǔ)句上方另起一行,使用//注釋;
方法內(nèi)部多行注釋使用/* */注釋,注意與代碼對(duì)齊。【強(qiáng)制】所有的常量類型字段必須要有注釋,說(shuō)明每個(gè)值的用途;
【參考】注釋掉的代碼盡量要配合說(shuō)明,而不是簡(jiǎn)單的注釋掉。
說(shuō)明:代碼被注釋掉有兩種可能性:
1)后續(xù)會(huì)恢復(fù)此段代碼邏輯。
2)永久不用。前者如果沒(méi)有備注信息,難以知曉注釋動(dòng)機(jī)。后者建議直接刪掉(代碼倉(cāng)庫(kù)保存了歷史代碼)。【參考】對(duì)于注釋的要求:
第一、能夠準(zhǔn)確反應(yīng)設(shè)計(jì)思想和代碼邏輯;
第二、能夠描述業(yè)務(wù)含義,使別的程序員能夠迅速了解到代碼背后的信息。完全沒(méi)有注釋的大段代碼對(duì)于閱讀者形同 天書,注釋是給自己看的,即使隔很長(zhǎng)時(shí)間,也能清晰理解當(dāng)時(shí)的思路;注釋也是給繼任者看的,使其能夠快速接替自己的工作。【參考】好的命名、代碼結(jié)構(gòu)是自解釋的,注釋力求精簡(jiǎn)準(zhǔn)確、表達(dá)到位。避免出現(xiàn)注釋的一個(gè)極端:過(guò)多過(guò)濫的注釋,代碼的邏輯一旦修改,修改注釋是相當(dāng)大的負(fù)擔(dān)。
- 【參考】特殊注釋標(biāo)記,請(qǐng)注明標(biāo)記人與標(biāo)記時(shí)間。注意及時(shí)處理這些標(biāo)記,通過(guò)標(biāo)記掃描,經(jīng)常清理此類標(biāo)記。
- 待辦事宜(TODO):( 標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間]) 表示需要實(shí)現(xiàn),但目前還未實(shí)現(xiàn)的功能。
- 錯(cuò)誤,不能工作:(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])
在注釋中用 FIXME標(biāo)記某代碼是錯(cuò)誤的,而且不能工作,需要及時(shí)糾正的情況。
(七) 日志管理
【推薦】 代碼中過(guò)多使用console.log()會(huì)消耗性能,推薦去除不必要的日志輸入代碼;
-
【強(qiáng)制】 在入口文件添加以下代碼;
說(shuō)明:可以在發(fā)布時(shí)屏蔽掉所有的console.*調(diào)用。React Native中有一個(gè)全局變量DEV用于指示當(dāng)前運(yùn)行環(huán)境是否是開發(fā)環(huán)境。我們可以據(jù)此在正式環(huán)境中替換掉系統(tǒng)原先的console實(shí)現(xiàn)。if (!__DEV__) { global.console = { info: () => {}, log: () => {}, warn: () => {}, error: () => {}, }; }
這樣在打包發(fā)布時(shí),所有的控制臺(tái)語(yǔ)句就會(huì)被自動(dòng)替換為空函數(shù),而在調(diào)試時(shí)它們?nèi)匀粫?huì)被正常調(diào)用。
(八) 目錄結(jié)構(gòu)規(guī)范
以下目錄結(jié)構(gòu)示例中只展示js與靜態(tài)資源,不包含原生代碼:
├── index.ios.js
├── index.android.js
└── js
├── component 可復(fù)用的組件(非完整頁(yè)面)
├── controller 完整頁(yè)面
├── data 配置項(xiàng)(常量、接口地址、路由、多語(yǔ)言化等預(yù)置數(shù)據(jù))
├── utils 工具類(非UI組件)
├── common 公共
└── assets 圖片
在component和controller目錄中,可能還有一些內(nèi)聚度較高的模塊再建目錄
controller/component
├── HomeView.component.js
├── HomeView.style.js
└── MovieView
├── MovieList.component.js
├── MovieList.style.js
├── MovieCell.component.js
├── MovieCell.style.js
├── MovieView.component.js
└── MovieView.style.js
二、頁(yè)面編寫規(guī)范
(一) state,props
【強(qiáng)制】 代碼中初始化state因在constructor(props)函數(shù)中,而且盡量對(duì)每個(gè)變量進(jìn)行注釋;
-
【強(qiáng)制】 代碼中使用setState時(shí),因注意異步可能導(dǎo)致的問(wèn)題,盡量使用回調(diào)函數(shù);
this.setState({ //todo },()=>{ //執(zhí)行setState后執(zhí)行此函數(shù) }) -
【強(qiáng)制】 代碼中使用props時(shí),需進(jìn)行propTypes檢測(cè)和defaultProps默認(rèn)值初始化;
static propTypes = { color: PropTypes.string, dotRadius: PropTypes.number, size: PropTypes.number }; static defaultProps = { color: '#1e90ff', dotRadius: 10, size: 40 };
4.【強(qiáng)制】 代碼中用于頁(yè)面展示處理UI的組件,命名以Page結(jié)尾,自定義組件命名中必須包含Component;
例子:
LoginController 登錄頁(yè)
BtuuonComponent 按鈕組件
5.【強(qiáng)制】代碼中創(chuàng)建數(shù)組或?qū)ο笫褂靡韵路绞剑?/p>
const user={
name:'time',
sex:'男',
age:25,
};
const itemArray=['0','1','2',3,{name:'25',age:'男'}];
6.【強(qiáng)制】代碼中函數(shù)綁定this,強(qiáng)制使用箭頭函數(shù);
注:除組件原有方法,其他自定義函數(shù)命名時(shí),需使用箭頭函數(shù);
//系統(tǒng)組件生命周期方法
constructor(props){
super(props);
};
//自定義方法
goMainPage=()=>{
};
7.【推薦】代碼中一些網(wǎng)絡(luò)數(shù)據(jù)初始化,配置信息,推薦在此生命周期進(jìn)行初始化;
componentWillMount
8.【強(qiáng)制】代碼中使用定時(shí)器或者DeviceEventEmitter,必須在組件卸載進(jìn)行銷毀或者清除;
componentDidMount() {
//注意addListener的key和emit的key保持一致
this.msgListener = DeviceEventEmitter.addListener('Msg',(listenerMsg) => {
this.setState({
listenerMsg:listenerMsg,
})
});
}
goMainPage=()=>{
this.timer = setTimeout(
() => { console.log('把一個(gè)定時(shí)器的引用掛在this上'); },
500
);
};
componentWillUnmount() {
//此生命周期內(nèi),去掉監(jiān)聽和定時(shí)器
this.msgListener&&this.msgListener.remove();
// 如果存在this.timer,則使用clearTimeout清空。
// 如果你使用多個(gè)timer,那么用多個(gè)變量,或者用個(gè)數(shù)組來(lái)保存引用,然后逐個(gè)clear
this.timer && clearTimeout(this.timer);
}
9.【強(qiáng)制】使用本地圖片資源時(shí),需設(shè)置寬高并進(jìn)行適當(dāng)適配;
imgHeight=screenHeight, imgWidth= screenWidth
10.【強(qiáng)制】在React-Native版本小于0.46.0使用本地圖片資源時(shí),當(dāng)不指定特殊尺寸圖片時(shí),需引入不同尺寸XX.png,XX2@.png,XX3@.png圖片,并在代碼引用中,使用如下方式:
<Image style={{flex: 1, height: screenHeight, width: screenWidth}}
source={require('../XX.png')}>
說(shuō)明:當(dāng)使用XX.png時(shí),程序運(yùn)行過(guò)程中會(huì)根據(jù)不同屏幕尺寸獲取不同資源;當(dāng)使用如下方式:
<Image style={{flex: 1, height: screenHeight, width: screenWidth}}
source={require('../XX2@.png')}>
時(shí),程序運(yùn)行過(guò)程中不會(huì)根據(jù)不同屏幕尺寸獲取不同資源。
注意:此方式適用于React-Native0.46.0版本之前。
9.【強(qiáng)制】在React-Native版本大于0.46.0使用本地資源,圖片命名不能出現(xiàn)‘@’符號(hào):
說(shuō)明:不同大小圖片需要原生不同的尺寸文件夾,系統(tǒng)自動(dòng)進(jìn)行不同適配。
(二) 樣式
-
【強(qiáng)制】 當(dāng)組件使用樣式屬性達(dá)到三個(gè)或者三個(gè)以上時(shí),必須使用StyleSheet來(lái)創(chuàng)建樣式屬性并進(jìn)行引用;
const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', marginTop:10, }, }); -
【推薦】 當(dāng)使用單一屬性,或者全局樣式屬性時(shí),推薦使用公共樣式類;
//StyleCommon.js module.exports={ topColor:{ backgroundColor: '#3A3D42', }, mainView:{ backgroundColor: '#12141B', }, } -
【推薦】 當(dāng)使用多個(gè)state或者props值時(shí),推薦使用以下方式;
const {size, dotRadius, color} = this.props; const { maxNumber,minNumber,}=this.state;
說(shuō)明使用此方式,代碼結(jié)構(gòu)清晰簡(jiǎn)潔,便于維護(hù);
(三) var,let,const
- 【強(qiáng)制】對(duì)所有變量,對(duì)象的引用,使用const,不要使用var;
- 【推薦】如果一定需要引用可變動(dòng)的變量,對(duì)象,建議使用let代替var;
(四) 代碼間隔
- 【強(qiáng)制】使用ES6編寫代碼,定義方法時(shí),每個(gè)方法結(jié)尾使用‘;’進(jìn)行分隔;
(五) 其他
-
【強(qiáng)制】對(duì)組件引用,變量引用,需遵從以下方式;
import React, {Component} from 'react'; import{ View, Text, TouchableHighlight, Image, StyleSheet, InteractionManager, } from 'react-native'; //from react,react-native優(yōu)先; //from npm庫(kù)其次; import { connect } from 'react-redux'; //from 項(xiàng)目?jī)?nèi)組件其次; import LoadingAndTime from '../component/LoadingAndTime'; import { performLoginAction } from '../action/LoginAction' import {encode} from '../common/Base64'; //變量初始化,常量初始化 最后; let screenWidth = Dimensions.get('window').width; let screenHeight = Dimensions.get('window').height; let typeCode = Platform.OS == 'android' ? 'android-phone' : 'ios-phone' let selectColor=Platform.OS=='android'?null:'white' 【推薦】對(duì)組件引用,變量初始化等,在整個(gè)頁(yè)面或組件內(nèi)未使用,因去除相關(guān)代碼;
【推薦】某些全局變量請(qǐng)不要使用global,需新建文件進(jìn)行導(dǎo)出引用;
NetUtil.get(global.url + “”)【推薦】render()函數(shù)代碼過(guò)長(zhǎng)時(shí),請(qǐng)適當(dāng)進(jìn)行拆分,拆分為‘‘頁(yè)面內(nèi)組件‘‘,提高可讀性。render()函數(shù)代碼行請(qǐng)勿超過(guò)八十行,超過(guò)之后,請(qǐng)自行進(jìn)行拆分;
三、編碼約定
(一)入口文件
1.【推薦】統(tǒng)一入口文件為App.js;
說(shuō)明:在index.android.js和index.ios.js文件中,統(tǒng)一入口文件為App.js,且保持所在目錄和index.android.js和index.ios.js同級(jí)。
2.【強(qiáng)制】開發(fā)中,不要使用任何后端的開發(fā)模式來(lái)構(gòu)建APP結(jié)構(gòu),如使用MVC,MVP,MVVM等開發(fā)模式,React-Native推薦組件化,顆?;?,以上設(shè)計(jì)模式嚴(yán)重違背。若使用Redux,Mobx等數(shù)據(jù)流第三方,可依據(jù)第三方結(jié)構(gòu)編寫構(gòu)建App。
3.【推薦】某些輸入框的值,放入到state中,并且設(shè)置defaultValue,不要使用全局變量進(jìn)行引用,參照以下方式:
constructor(props) {
super(props);
this.state = {
editSalesPrice:'', //修改后的商品售價(jià)
editPurchasePrice:'', //修改后的商品進(jìn)價(jià)
};
}
render(){
return(
<View style={styles.viewPadding}>
<TextInput
style={styles.rowInput}
placeholder="請(qǐng)輸入調(diào)整后的價(jià)格"
onChangeText={(text)=>{
this.setState({
editSalesPrice:text,
})
}}
defaultValue={this.state.editSalesPrice}
placeholderTextColor='#B0B7C2'
underlineColorAndroid = 'transparent'
autoCapitalize={'none'}
autoCorrect={false}
clearButtonMode={'while-editing'}
keyboardType='numeric'
/>
</View>
);
}
4.【強(qiáng)制】移除定時(shí)器,監(jiān)聽請(qǐng)按照如下代碼進(jìn)編寫;
componentWillUnmount() {
//此生命周期內(nèi),去掉監(jiān)聽和定時(shí)器
this.msgListener && this.msgListener.remove();
// 如果存在this.timer,則使用clearTimeout清空。
this.timer && clearTimeout(this.timer);
}
(二) 模版文件
1.【推薦】根據(jù)附件,配置代碼編寫模版,推薦使用第二種配置方式,可配置多種模版。
(三) ListView,FaltList
1.【強(qiáng)制】使用ListView或者FaltList的renderRow時(shí),需對(duì)renderRow里面的組件需進(jìn)行抽取,使用一個(gè)單獨(dú)組件進(jìn)行包裹,類似于頁(yè)面子組件方式引入;
請(qǐng)勿使用如下方式:
renderRow(news) {
return (
<TouchableOpacity onPress={() => {
this.onPress(news)
}} style={styles.container}>
<Image source={require('../imgs/icon_data.png')}/>
<View style={styles.row_main}>
<Text style={styles.row_title}>{news.belOutlet}</Text>
<Text style={styles.row_bottom}>所屬支行:{news.belBranch}</Text>
</View>
{this._renderNewFlag(news)}
</TouchableOpacity>
);
}
推薦使用如下方式:
import GoodInCell from './GoodInCell';
renderRow(news) {
return (
<GoodInCell news={news} />
);
}
說(shuō)明:使用此方式,可增加代碼的可讀性和理解性。更符合組件化的開發(fā)思路。
四、自定義組件
(一) 自定義組件
-
【強(qiáng)制】組件命名中必須包含Component;
說(shuō)明:ButtonComponent.js
LabelComponent.js 【強(qiáng)制】組件中定義的state和props必須都要有注釋,依次說(shuō)明每個(gè)值的含義;
【強(qiáng)制】在每個(gè)類的頭部注釋中,必須使用/**/說(shuō)明此組件的基礎(chǔ)使用方式以及特殊使用方法;
(二) 屬性判斷
-
【強(qiáng)制】代碼中使用props時(shí),需進(jìn)行propTypes檢測(cè)和defaultProps默認(rèn)值初始化;
static propTypes = {
color: PropTypes.string,
dotRadius: PropTypes.number,
size: PropTypes.number
};static defaultProps = {
color: '#1e90ff',
dotRadius: 10,
size: 40
};
2.【強(qiáng)制】代碼中使用props方法時(shí),具體參照以下方式進(jìn)行調(diào)用;
export default class PostCallMsgToPar extends Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.postMsgByCallBack}>
<Text>使用Callback修改父狀態(tài),無(wú)返回值</Text>
</TouchableOpacity>
</View>
);
}
postMsgByCallBack=()=>{
if(this.props.onChangeMsg){
this.props.onChangeMsg();
}
}
}
(三) 性能優(yōu)化
-
【強(qiáng)制】無(wú)狀態(tài)組件需使用PureComponent而不是Component;
說(shuō)明:無(wú)狀態(tài)組件是指內(nèi)部沒(méi)有使用state的組件,但是可以使用props來(lái)進(jìn)行某些屬性控制;export default class LinkButton extends PureComponent {
static defaultProps= {
msgName:'請(qǐng)輸入此事件函數(shù)名!'
};static propTypes={ msgName:PropTypes.string.isRequired, onPressCall:PropTypes.func, }; render() { return ( <View style={styles.container}> <TouchableOpacity onPress={this.onPressCall} > <View> <Text>{this.props.msgName}</Text> </View> </TouchableOpacity> </View> ); } onPressCall=()=>{ if(this.props.onPressCall){ this.props.onPressCall(); } }}
2.【推薦】使用InteractionManager.runAfterInteractions,在動(dòng)畫或者某些特定場(chǎng)景中利用InteractionManager來(lái)選擇性的渲染新場(chǎng)景所需的最小限度的內(nèi)容;
使用場(chǎng)景類似于:
class ExpensiveScene extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {renderPlaceholderOnly: true};
}
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
this.setState({renderPlaceholderOnly: false});
});
}
render() {
if (this.state.renderPlaceholderOnly) {
return this.renderPlaceholderView();
}
return (
<View>
<Text>Your full view goes here</Text>
</View>
);
}
renderPlaceholderView() {
return (
<View>
<Text>Loading...</Text>
</View>
);
}
};
說(shuō)明:更多使用于Navigator的頁(yè)面跳轉(zhuǎn)
3.【推薦】使用新版本組件替換舊辦法組件;
例如:FlatList替換ListView,React Navigation替換Navigator等
4.【推薦】在使用Touchable系列組件時(shí),進(jìn)行setState或者大量調(diào)幀操作,請(qǐng)使用如下方式:
handleOnPress() {
this.requestAnimationFrame(() => {
//todo
});
}
五、安全規(guī)約
【強(qiáng)制】用戶敏感數(shù)據(jù)禁止直接展示,必須對(duì)展示數(shù)據(jù)脫敏; 說(shuō)明:查看個(gè)人手機(jī)號(hào)碼會(huì)顯示成:158****9119,隱藏中間 4 位,防止隱私泄露
【強(qiáng)制】請(qǐng)求傳入任何參數(shù)必須做有效性驗(yàn)證;避免過(guò)度請(qǐng)求服務(wù),造成服務(wù)器壓力,或者雙向校驗(yàn);
如:驗(yàn)證手機(jī)號(hào)長(zhǎng)度,是否是手機(jī)號(hào)等;
六、其他
【推薦】開發(fā)工具使用WebStorm,安裝ESLint插件進(jìn)行代碼檢測(cè),代碼中不要出現(xiàn)使用ESLint檢查出的錯(cuò)誤;
說(shuō)明:變量命名規(guī)范,使用var或者const錯(cuò)誤【推薦】在WebStorm中導(dǎo)入附件的hoop-settings.jar文件,進(jìn)行代碼格式化,提交的任何代碼,都需要進(jìn)行格式化??旖萱I是option+command+L。