一、命名规范
1、通用命名方法
命名方法 | 举例 |
---|---|
Camel命名法 | thisIsAnApple |
Pascal命名法 | ThisIsAnApple |
注意:在命名时尽量简洁明了,用英文表达(尽量不要用拼音或者首字母拼写)
2、各类型命名规范
名称 | 命名方法 | 词汇种类 | 说明 | 举例 |
---|---|---|---|---|
局部变量名 | Camel命名法 | 名词 | fristName | |
参数名 | Camel命名法 | 名词 | fristName | |
方法/属性 | Camel命名法 | 名词 | fristName | |
常量名 | 名词 | 下划线+全体大写 | ADD_METHOD | |
类名 | Pascal命名法 | 名词 | AtiveDic | |
Bool类型 | Camel命名法 | 名词 | 前缀:is/has | hasChild |
3、文件命名
名称 | 命名方法 | 说明 | 举例 |
---|---|---|---|
文件夹 | 全小写 | 过长用减号-连接 | auto-complete |
文件-样式 | 全小写 | 过长用减号-连接 | page-style.less |
文件-index(特例) | 全小写 | 方便省略引入 | page/index.jsx |
文件-组件 | Pascal命名法 | CalenderCustome | |
文件-store | Pascal命名法 | FlowSituation | |
扩展名 | .jsx | 统一命名 | page.jsx |
4、函数与类的命名
Ⅰ.函数
1)使用Camel命名法
2)前缀为动词,前缀词如下表所示
动词 | 含义 | 举例 |
---|---|---|
can | 判断是否可以执行某个权限 | canLogin |
has | 判断是否含有某个值 | hasToken |
is | 判断是否为某个值 | isShowModel |
get | 获取某个值 | getUserId |
set | 设置某个值 | setCookie |
load | 加载某些数据 | loadList |
update | 更新某些数据 | updateUserInfo |
del | 删除某些数据 | delMenu |
Ⅱ、类(Class)命名规范
1)使用Pascal命名法
2)名字应该明确表达改类的作用
Ⅲ、事件方法命名
在 React 中,有一个命名规范,通常会将代表事件的监听 prop 命名为 on[Event],将处理事件的监听方法命名为 handle[Event] 这样的格式。
二、props与state的使用
1、Props
定义:大多数组件在定义时就可以通过各种自定义参数来实现组件的定制。
编程注意事项:
在页面中禁止直接修改props
this.props.name = 'Alen'
。在调用props时尽量使用扩展符。
//good
const { name } = this.porps;
console.log(name);
//bad
console.log(this.props.name);
2、State
定义:State是一个组件的UI数据模型,是组件渲染时的数据依据。
编程注意事项:
在调用state时尽量使用扩展符。
setState是异步的,若执行setState后需马上调用,可以使用这些方法转化为同步。(方法)
//good
this.setState((prevState, props) => ({
name: prevState.name + props.increment
}));
//bad
this.setState({name:this.state.name});
5.禁止在shouldComponentUpdate或者componentWillUpdate方法中调用setState
三、React编码规范
1、自我解释
尽可能减少代码中的注释。可以通过让变量名更语义化、只注释复杂、潜在逻辑,来减少注释量,同时也提高了可维护性,毕 竟不用总在代码与注释之间同步了。
2、JSX编码
1.在JSX中禁止使用if语句进行判定
//bad
ShowUserInfo{
if(isShowUserInfo){
retrun(
<div>姓名:张三</div>
);
}else{
return(
<div>姓名:未填写</div>
)
}
}
//good
ShowUserInfo(){
return isShowUserInfo ? (<div>姓名:张三</div>) : (<div>姓名:未填写</div>)
}
三目运算:条件1?值1或操作1: //如果满足条件1,就返回值1或执行操作1
2.尽量使用单标签
//bad
render(){
return(
<div>
...
<UserInfo></UserInfo>
...
</div>
);
}
//good
render(){
return(
<div>
...
<UserInfo />
...
</div>
);
}
3.在标签中默认的都是true
//bad
<Foo
hidden={true}
/>
//good
<Foo hidden />
4.在map循环时,不要用index作为每个标签的key
// bad
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
// good
{todos.map(todo => (
<Todo
{...todo}
key={todo.id}
/>
))}
5.使用ref的回调
// bad
<Foo
ref="myRef"
/>
// good
<Foo
ref={(ref) => { this.myRef = ref; }}
/>
更多JSX规范参见:更多规范
3、解构
// bad
const splitLocale = locale.split('‑');
const language = splitLocale[0];
const country = splitLocale[1];
// good
const [language, country] = locale.split('‑');
4、变量判定
1.对所有定义的或者传入的变量,都进行默认设置或者判定是否为undefined,防止数据未定义时程序报错。
// Bad
onChange(value => console.log(value.name))
// Dirty
onChange((value) => {
if (!value) {
value = {}
}
console.log(value.name)
})
// Clean
onChange((value = {}) => console.log(value.name))
不要信任任何回调函数给你的变量,它们随时可能是 undefined ,使用初始值是个不错的选择,但有的时候初始值没什么意 义,使用 ?. 语法可以安全的访问属性。
2.自定义变量
//bad
let newslist = this.props.newslist;
let b = a // a为数组
//good
let { newslist = [] } = this.props;
let b = a || [];
四、React中常用ES6语法
1、变量解构
1.数组与数组合并
let a = [1,2];
let b = [3,4];
//bad
let c = a.concat(b); // [1,2,3,4]
//OR
for(let i = 0 ;i<b.length;i++){
a.push(b[i]);
}
//good
let c = [...a,...b]; // [1,2,3,4]
2.对象与对象合并
let a = {name:'张三'}
let b = {age:32}
//bad
let c = {
name:a.name,
age:b.age
}
//good
let c = {...a,...b};
3.对象并入数组
let a = [{name:'张三'}];
let b = {name:'Lucy'};
//bad
let c = a.push(b);
//good
let c = [...a,b];
4.数值互换
let a = 1;
let b = 2;
//bad
let t;
t = a;
a = b;
b = t;
//good
[a,b] = [b,a];
2、遍历
注意:在遍历过程中禁止删除、新增
1.数组遍历
let a = [1,2,3,4,5];
//不推荐,但是可视具体业务使用不同的循环
for(let i = 0;i<a.length;i++){
console.log(a[i]);
}
//good
a.forEach(e=>{
console.log(e);
})
//OR
a.map(e=>{
console.log(e);
});
2.对象遍历
let a = {name:'Lucy',age:32,sex:'女'};
//bad
for(o in a){
console.log(a[o]);
}
//good
for(o in a){
if(a.hasOwnProperty(o)){
console.log(a[o]);
}
}
参考文献:for...in... for...of... 注意:二者有巨大区别,慎用
3、值判断
1.判空
if([]){
console.log('1');
} // 1
if({}){
console.log('1');
} // 1
if(''){
console.log('1');
}
变量如果不为0,null,undefined,false,都会被处理为true。只要变量有非0的值或是某个对象,数组,非空字符串,都会认为true
2.true || false
console.log([] == false); // true
console.log({} == false); // false
console.log('' == false); // true
console.log(0 == false); //true
3.typeof类型判断
类型 | 结果 |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Symbol | "symbol" |
宿主对象 | Implementation-dependent |
函数对象 | "function" |
任何其他对象 | "object" |
五、CSS注意事项
- 有多个选择器公用同一css代码块时,选择器应以逗号分隔,并换行
//bad
.right-header,.screen-detail-title,.screen-control-title {
position: relative;
height: 40px;
width: 100%;
}
//good
.right-header,
.screen-detail-title,
.screen-control-title {
position: relative;
height: 40px;
width: 100%;
}
- 对于属性值或颜色参数,省略小数前面的 0 (例如,.5 代替 0.5;-.5px 代替 -0.5px);
//bad
background-color:rgba(0, 0, 0, 0.5);
//good
background-color:rgba(0, 0, 0, .5);
- 十六进制值应该全部小写和尽量简写,例如,#fff 代替 #ffffff;
//bad
box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
//good
box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #fff
- 避免为 0 值指定单位,例如,用 margin: 0; 代替 margin: 0px;;
- 媒体查询(Media query)的位置
将媒体查询放在尽可能相关规则的附近。不要将他们打包放在一个单一样式文件中或者放在文档底部。如果你把他们分开了,将来只会被大家遗忘
.element { ... }
.element-avatar { ... }
.element-selected { ... }
@media (max-width: 768px) {
.element { ...}
.element-avatar { ... }
.element-selected { ... }
}
六、排版
1、 对齐
为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>
2、引号
JSX的属性都采用双引号,其他的JS都使用单引号:jsx-quotes。
为什么这样做?JSX 属性 不能包含转义的引号, 所以当输入"don't"这类的缩写的时候用双引号会更方便。
// bad
<Foo bar='bar' />
// good
<Foo bar="bar" />
// bad
<Foo style={{ left: "20px" }} />
// good
<Foo style={{ left: '20px' }} />
2、属性
- 属性名称始终使用驼峰命名法。
// bad
<Foo
UserName="hello"
phone_number={12345678}
/>
// good
<Foo
userName="hello"
phoneNumber={12345678}
/>
3、括号
使用括号包裹多行JSX标签,react/wrap-multilines
// bad
render() {
return <MyComponent className="long body" foo="bar">
<MyChild />
</MyComponent>;
}
// good
render() {
return (
<MyComponent className="long body" foo="bar">
<MyChild />
</MyComponent>
);
}
// good, when single line
render() {
const body = <div>hello</div>;
return <MyComponent>{body}</MyComponent>;
}
4、方法
在 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} />
}
}
5、排序
class extends React.Component的顺序:
- static静态方法
- constructor
- getChildContext
- componentWillMount
- componentDidMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
- 点击回调或者事件回调 比如 onClickSubmit() 或者 onChangeDescription()
- render函数中的 getter 方法 比如 getSelectReason() 或者 getFooterContent()
七、注释
1、文件头部注释
/* ------------------------------------------------------------
author : cattleya
create:2016-12-30
descreption:recharge相关样式(包含input/label/button)
------------------------------------------------------------ \*/
2、函数注释
函数注释,可使用块级注释
/*
*函数注释
*@ param {string} p1 参数1的说明
*@ param {string} p2 参数2的说明,比较长
*@ return 返回值描述
*/
aa() => {
alert();
}
参考文献:
React编程规范
typeof
React代码开发规范
React规范