1、定义state
在constructor里初始化state的值
constructor(props){
super(props)
this.state = {
count:0
}
}
2、修改state
修改state的唯一方法是setState(),这个方法是异步的,state的更新是浅合并的过程。
this.setState({
count: this.state.count-1
}, ()=>{
// 这时更新了state.count
})
3、不可变原则——创建新的状态
(1)值类型
this.setState({
count: 99,
name: '数字电视',
show: true
})
(2)数组
const _books = [...this.state.books, 'new book'];或
const _books = this.state.books.concat('new book');
this.setState({
books: _books
})
(3)对象
item = {
id: 1,
name: 'sony TV',
price: 6000
}
const _item = Object.assign({},this.state.item,{price:8000}) 或者
const _item = {...this.state.item, price:8000}
this.setState({
item: _item
})
4、通过条件判断优化渲染
方法一:shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState)是重新渲染时,render方法执行前调用。它可以有效阻止不必要的render方法的执行。
注意:不能用this.props和nextProps直接比对,因为他们是不同的引用,只可以比对其中的值。
shouldComponentUpdate(nextProps, nextState){
if(nextState.count===this.state.count){
return false
}
return true
}
方法二:PureComponent(推荐)
import React, { PureComponent } from 'react';
class ListItem extends PureComponent {
// TODO
}
建议使用pureComponent优化react应用。
5、使用不可变数据——单一数据源:
使用PureComponent,UI并不会更新。因为在js中,基本类型存在于栈内存中,obj、func、Array引用类型的变量存在于堆内存中。不同引用指向堆内存中的同一对象。见下图:
image.png
所以要用不可变数据,生成一个新对象。这样,新对象和原来的state引用的是不同的对象,就可以触发UI更新了。所以,要用不可变数据修改state/props值。
this.state={
count: this.props.data.value
}
handleAmount = () => {
const _list = this.state.listData.concat([]); // 用concat生成一个新数组
_list.pop();
this.setState({
listData: _list
})
}
handleReset = ()=>{
const _list = this.state.listData.map(item=>{
const _item = {…item}
_item.value=0
return _item
})
this.setState({
listData: _list
})
}
去掉子组件的state,去掉子组件的constructor方法。生成新数据,如使用concat。
6、状态提升
image.png如上图所示,所有子组件的数据都来自父辈组件,父辈组件统一存储修改数据再传入子组件。子组件调用事件处理函数,来使用父组件的方法,控制state数据的更新。
7、使用无状态组件
有状态组件和无状态组件的区别如下:
类组件 & 函数组件.png注:尽量通过状态提升原则,将需要的状态提取到父组件中,其他组件使用无状态组件编写。
网友评论