1、最重要的生命周期规范
class Example extends Component {
// 静态属性
static defaultProps = {}
// 构造函数
constructor(props) {
super(props);
this.state={}
}
// 声明周期钩子函数
// 按照它们执行的顺序
// 1. componentWillMount
// 2. componentWillReceiveProps
// 3. shouldComponentUpdate
// 4. componentDidMount
// 5. componentDidUpdate
// 6. componentWillUnmount
componentDidMount() { ... }
// 事件函数/普通函数
handleClick = (e) => { ... }
// 最后,render 方法
render() { ... }
}
2、无状态组件: 函数式组件
无交互逻辑和业务数据
没有使用构造函数、没有使用方法,没必要使用class继承
only Render函数
性能好
import React from "react";
import List from '../../pages/list/list';
const Index = () => {
return(
<div style={{paddingTop:'50px',width: '600px', margin: '0 auto'}}>
<List/>
</div>
)
};
export default Index;
3、有状态组件: class
丰富的交互逻辑和业务数据
import React, { Component } from "react";
import ListInput from "./components/ListInput";
import ListLi from './components/ListLi'
import { Card, Button } from "antd";
class List extends Component{
constructor(props) {
super(props);
this.state = {
list: ['测试1', '测试2'],
value: ''
};
};
// 增加
addItem = () => {
let { list, value } = this.state;
if(!value){
return;
}
list.push(value);
value = '';
this.setState({
list,
value
},() => {
console.log(this.ul.querySelectorAll('li').length);
});
};
// 改变
onChange = (content) => {
let { value } = this.state;
value = content;
this.setState({
value
})
};
// 删除
deleteItem = (index) => {
let { list } = this.state;
list.splice(index, 1);
this.setState({
list
})
};
render() {
console.log('组件挂在中');
let { list, value } = this.state;
const listLi = list.map((item, index) => {
return (
<ListLi key={index} item={item} index={index} deleteItem={this.deleteItem.bind(this)} />
)
});
const noLi = '暂无更多';
return (
<div style={{width: '100%'}}>
<Card title='todo' style={{marginBottom: '30px'}}>
<ListInput value={value} onChange={this.onChange.bind(this)} />
<Button style={{marginTop: '30px'}} type='primary' onClick={ this.addItem } >新增</Button>
</Card>
<Card title='列表' style={{marginBottom: '30px'}}>
<ul ref={(ul) => {this.ul = ul}}>
{
list.length > 0 ? listLi : noLi
}
</ul>
</Card>
</div>
)
}
}
export default List
4、redux的使用
一、使用actionTypes规范每个action的名字,避免写错不报错的发生
二、actionCreators统一创建action,避免往后逻辑混乱
5、组件声明
推荐
import Footer from './Footer';
不推荐
import Footer from './Footer/index';
6、组件声明
-
组件名称: 推荐使用大驼峰命名;
-
属性名称: React DOM 使用小驼峰命令来定义属性的名称,而不使用 HTML 属性名称的命名约定;
-
style 样式属性: 采用小驼峰命名属性的 JavaScript 对象
推荐
// 组件名称
MyComponent
// 属性名称
onClick
// 样式属性
backgroundColor
7、JSX 写法注意
1、标签
(1)当标签没有子元素的时候,始终使用自闭合的标签 。
// Good
<Component />
(2)如果标签有多行属性,关闭标签要另起一行
<Component
bar="bar"
baz="baz"
/>
(3)在自闭标签之前留一个空格。
<Foo />
(4)当组件跨行时,要用括号包裹 JSX 标签。
render() {
return (
<MyComponent className="long body" foo="bar">
<MyChild />
</MyComponent>
);
}
2、对齐
// 推荐
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
/>
// 如果组件的属性可以放在一行(一个属性时)就保持在当前一行中
<Foo bar="bar" />
// 多行属性采用缩进
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
>
<Quux />
</Foo>
3、引号
JSX 的属性都采用双引号,其他的 JS 都使用单引号 ,因为 JSX 属性 不能包含转义的引号, 所以当输入 "don't" 这类的缩写的时候用双引号会更方便。
<Foo bar="bar" />
<Foo style={{ left: '20px' }} />
8、defaultProps 使用静态属性定义
defaultProps 推荐使用静态属性定义,不推荐在 class 外进行定义。
推荐:
class Example extends React.Component {
static defaultProps = {
name: 'stranger'
}
render() {
// ...
}
}
不推荐:
class Example extends React.Component {
render() {
// ...
}
}
Example.propTypes = {
name: PropTypes.string
};
9、key 属性设置
key的值等于id更好
万不得已可以使用元素索引 index 作为 key,但是要主要如果列表项目的顺序可能会变化,如果使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。
10、State
1、不要直接修改 state
除了 state 初始化外,其它地方修改 state,需要使用 setState( ) 方法,否则如果直接赋值,则不会重新渲染组件。
// 推荐:
this.setState({comment: 'Hello'});
// 不推荐:
this.state.comment = 'hello';
2、State 的更新可能是异步的
// 推荐:
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
// 不推荐:
this.setState({
counter: this.state.counter + this.props.increment,
});
11、状态提升
如果多个组件需要反映相同的变化数据,建议将共享状态提升到最近的共同父组件中去;从而依靠自上而下的数据流,而不是尝试在不同组件间同步 state。
12、路由加载
建议使用路由懒加载当前用户所需要的内容,这样能够显著地提高你的应用性能。尽管并没有减少应用整体的代码体积,但你可以避免加载用户永远不需要的代码,并在初始加载的时候减少所需加载的代码量。
// 推荐:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
// 不推荐:
import OtherComponent from './OtherComponent';
13、Axios发起请求时机
componentDidMount这个生命周期发起请求比较合理
14、推荐使用 Context
如果某个属性在组件树的不同层级的组件之间需要用到,我们应该使用 Context 提供在组件之间共享此属性的方式,而不不是显式地通过组件树的逐层传递 props。