标签(空格分隔): React-Native JavaScript
LoginPage/MsgPage
localValue / getHttpMessage() / inputUserId
正例: MAX_STOCK_COUNT 反例: MAX_COUNT
userMsg 等价于 userMessaage, userPic 等价于 userPicture
正例: 应用工具类包名为com.fcs.open.util、类名为UrlUtils
if (condition) statements;
// 接着写 else 的业务逻辑代码; 说明:如果非得使用
if()
...
else if(
)...else...
方式表达逻辑,【强制】请勿超过3层, 超过请使用状态设计模式。 正例:逻辑上超过 3 层的 if-else 代码可以使用卫语句,或者状态模式来实现。
4.【推荐】使用三目运算,替换if else结构,精简代码
let account=5;
if(account>10){
console.log("true");
}else {
console.log("false");
}
let msg=account>10?"true":"false";
5.【推荐】除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复 杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。 说明:很多 if 语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么 样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?
//伪代码如下
boolean existed = (file.open(fileName, "w") != null)&& (...) || (...);
if (existed) {
...
}
这样在打包发布时,所有的控制台语句就会被自动替换为空函数,而在调试时它们仍然会被正常调用。
以下目录结构示例中只展示js与静态资源,不包含原生代码:
├── index.ios.js
├── index.android.js
└── js
├── component 可复用的组件(非完整页面)
├── controller 完整页面
├── data 配置项(常量、接口地址、路由、多语言化等预置数据)
├── utils 工具类(非UI组件)
├── common 公共
└── assets 图片
在component和controller目录中,可能还有一些内聚度较高的模块再建目录
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
4.【强制】 代码中用于页面展示处理UI的组件,命名以Page结尾,自定义组件命名中必须包含Component; 例子:
LoginController 登录页
BtuuonComponent 按钮组件
5.【强制】代码中创建数组或对象使用以下方式;
const user={
name:'time',
sex:'男',
age:25,
};
const itemArray=['0','1','2',3,{name:'25',age:'男'}];
6.【强制】代码中函数绑定this,强制使用箭头函数; 注:除组件原有方法,其他自定义函数命名时,需使用箭头函数;
//系统组件生命周期方法
constructor(props){
super(props);
};
//自定义方法
goMainPage=()=>{
};
7.【推荐】代码中一些网络数据初始化,配置信息,推荐在此生命周期进行初始化;
componentWillMount
8.【强制】代码中使用定时器或者DeviceEventEmitter,必须在组件卸载进行销毁或者清除;
componentDidMount() {
//注意addListener的key和emit的key保持一致
this.msgListener = DeviceEventEmitter.addListener('Msg',(listenerMsg) => {
this.setState({
listenerMsg:listenerMsg,
})
});
}
goMainPage=()=>{
this.timer = setTimeout(
() => { console.log('把一个定时器的引用挂在this上'); },
500
);
};
componentWillUnmount() {
//此生命周期内,去掉监听和定时器
this.msgListener&&this.msgListener.remove();
// 如果存在this.timer,则使用clearTimeout清空。
// 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear
this.timer && clearTimeout(this.timer);
}
9.【强制】使用本地图片资源时,需设置宽高并进行适当适配;
imgHeight=screenHeight, imgWidth= screenWidth
10.【强制】在React-Native版本小于0.46.0使用本地图片资源时,当不指定特殊尺寸图片时,需引入不同尺寸XX.png,XX2@.png,XX3@.png图片,并在代码引用中,使用如下方式:
<Image style={{flex: 1, height: screenHeight, width: screenWidth}}
source={require('../XX.png')}>
说明:当使用XX.png时,程序运行过程中会根据不同屏幕尺寸获取不同资源;当使用如下方式:
<Image style={{flex: 1, height: screenHeight, width: screenWidth}}
source={require('../XX2@.png')}>
时,程序运行过程中不会根据不同屏幕尺寸获取不同资源。 注意:此方式适用于React-Native0.46.0版本之前。
9.【强制】在React-Native版本大于0.46.0使用本地资源,图片命名不能出现‘@’符号: 说明:不同大小图片需要原生不同的尺寸文件夹,系统自动进行不同适配。
说明使用此方式,代码结构清晰简洁,便于维护;
NetUtil.get(global.url + “”)
1.【推荐】统一入口文件为App.js; 说明:在index.android.js和index.ios.js文件中,统一入口文件为App.js,且保持所在目录和index.android.js和index.ios.js同级。
2.【强制】开发中,不要使用任何后端的开发模式来构建APP结构,如使用MVC,MVP,MVVM等开发模式,React-Native推荐组件化,颗粒化,以上设计模式严重违背。若使用Redux,Mobx等数据流第三方,可依据第三方结构编写构建App。
3.【推荐】某些输入框的值,放入到state中,并且设置defaultValue,不要使用全局变量进行引用,参照以下方式:
constructor(props) {
super(props);
this.state = {
editSalesPrice:'', //修改后的商品售价
editPurchasePrice:'', //修改后的商品进价
};
}
render(){
return(
<View style={styles.viewPadding}>
<TextInput
style={styles.rowInput}
placeholder="请输入调整后的价格"
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.【强制】移除定时器,监听请按照如下代码进编写;
componentWillUnmount() {
//此生命周期内,去掉监听和定时器
this.msgListener && this.msgListener.remove();
// 如果存在this.timer,则使用clearTimeout清空。
this.timer && clearTimeout(this.timer);
}
1.【推荐】根据附件,配置代码编写模版,推荐使用第二种配置方式,可配置多种模版。
1.【强制】使用ListView或者FaltList的renderRow时,需对renderRow里面的组件需进行抽取,使用一个单独组件进行包裹,类似于页面子组件方式引入; 请勿使用如下方式:
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} />
);
}
说明:使用此方式,可增加代码的可读性和理解性。更符合组件化的开发思路。
(一) 自定义组件
(二) 属性判断
2.【强制】代码中使用props方法时,具体参照以下方式进行调用;
export default class PostCallMsgToPar extends Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.postMsgByCallBack}>
<Text>使用Callback修改父状态,无返回值</Text>
</TouchableOpacity>
</View>
);
}
postMsgByCallBack=()=>{
if(this.props.onChangeMsg){
this.props.onChangeMsg();
}
}
}
(三) 性能优化
2.【推荐】使用InteractionManager.runAfterInteractions,在动画或者某些特定场景中利用InteractionManager来选择性的渲染新场景所需的最小限度的内容; 使用场景类似于:
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>
);
}
};
说明:更多使用于Navigator的页面跳转 3.【推荐】使用新版本组件替换旧办法组件; 例如:FlatList替换ListView,React Navigation替换Navigator等
4.【推荐】在使用Touchable系列组件时,进行setState或者大量调帧操作,请使用如下方式:
handleOnPress() {
this.requestAnimationFrame(() => {
//todo
});
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。