React状态管理的详细解读
2019-07-05 本文已影响0人
stevekeol
1、React中的数据
站在组件的角度,React应用中流动的数据可以分为两种:
- 不可更改内容,但可以单向跨组件传递的
props
; - 可以更改内容,但不可以跨组件传递的
state
。
进一步说,props
和state
的区别在于:props
是外部传进来的;state
是属于组件自身内部的。
2、函数组件
函数组件又称为"无状态组件",只负责接收props
并返回UI。自身并不能拥有可改变的数据。
- 如果组件不需要追踪内部状态,尽量使用函数组件;
- 尽可能使用函数组件,将整个应用的UI拆分成尽可能小的单;
3、类组件
和函数组件相对应的,就是"类组件",也成为"有状态组件"/"容器组件"。
不同于函数组件,类组件拥有可以更改的内部数据state
。state
属性是一个对象,代表了组件的状态,对象的每一个属性名都代表组件的一个特定状态。
由于React把变化的数据封装在组件内部,并坚持单项数据流的原则。因此有了高度抽象的UI组件,并封装了复杂的业务逻辑。因此,可以构建、组合一系列小组件开发出大型应用。
//state在组件内部的使用方式
constructor(props) {
super(props);
this.state = {
visible: false,
isFetching: false,
isNew: true
};
this.onChange = this.onChange.bind(this);
}
通过让组件管理自己的状态,任何时候状态的变更都会令React自动更新响应的页面部分。这便是React构建组件的优势之一:当页面需要重新渲染时,我们仅仅需要思考的是如何更改状态,不必跟踪页面的哪些部分需要更改,不需要决定如何有效的重新呈现页面。
3.1 state
的修改
this.setState()
有两种方式使用该api:
- 设置对象参数
this.setState({
name: 'stevekeol'
})
- 设置函数参数(当组件需要一个新的state,该state的变化又依赖于旧的state的值)
this.setState((prevState) => ({
name: 'Mr.' + prevState.name
}))
疑问:直接修改state对象的属性不就可以了嘛,为何需要一个this.setState()?
解释:this.setState()的作用,不仅仅是对象属性值发生变化,还需要驱动整个UI进行重新渲染。
3.2深度解析this.setState
- setState不会立即改变React组件中state的值;
- setState通过引发一系列组件的生命周期的更新过程来引发重新绘制;
- 多次setState函数调用产生的效果会合并;
function updateName() {
this.setState({FirstName: 'Morgan'});
this.setState({LastName: 'Cheng'});
}
//相当于
function updateName() {
this.setState({FirstName: 'Morgan', LastName: 'Cheng'});
}
function incrementMultiple() {
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
}
//相当于
function incrementMultiple() {
const currentCount = this.state.count;
this.setState({count: currentCount + 1});
this.setState({count: currentCount + 1});
this.setState({count: currentCount + 1});
}
//相当于
function incrementMultiple() {
const currentCount = this.state.count;
this.setState({count: currentCount + 1});
}
综上,this.setState并不会立即更新。由此带来的副作用,如何解决呢?
- 首先,this.setState肯定还是不能立即更新state。否则就推翻了React的整个概念。
- this.setState的隐藏功能:this.setState可以接收一个
函数
作为参数!!!
function increment(state, props) {
return {count: state.count + 1};
}
function incrementMultiple() {
this.setState(increment);
this.setState(increment);
this.setState(increment);
}
//这样多次调用函数式的setState,可以保证每次调用increment时,state都合并了之前状态修改的结果。
this.setState
可以接收一个函数作为参数,该函数接收两个参数:当前的state,当前的props。该函数返回一个对象,代表对state所作的更改。注意,此时依赖的参数是state
,而不是this.state
。