react基础 react组件状态

组件状态

组件状态:组件可以自行维护的数据

组件状态仅在类组件有效

状态(state):本质上是类组件的一个属性,是一个对象

组件状态初始化

  1. 在constructor中初始化
1
2
3
4
5
6
7
constructor(props){
super(props);
// 初始化组件
this.state = {
lastTime:this.props.number
}
}
  1. 直接初始化,使用JS Next语法
1
2
3
4
5

// 初始化组件
state = {
lastTime: this.props.number,
};

组件状态的改变

不能直接改变状态,因为React无法监控到状态发生了变化。

必须使用 this.setState({}) 改变状态

一旦调用this.setState会导致组件重新渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
constructor(props){
super(props);
// 初始化组件
this.state = {
lastTime:this.props.number
}
this.timer = setInterval(()=>{
// 重新设置状态
this.setState({
lastTime:this.state.lastTime - 1
})
},1000)
}

setState

setState对状态的改变可能是异步的。

如果改变状态的代码处于某个HTML元素的事件中,则其时异步的,反之则为同步。

如果要获取状态的新值,需要在回调函数中获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import React, { Component } from "react";

// 倒计时组件
export default class Tick extends Component {
// 初始化组件
state = {
lastTime: this.props.number,
};
constructor(props) {
super(props);
// // 初始化组件
// this.state = {
// lastTime:this.props.number
// }
this.timer = setInterval(() => {
this.setState({
lastTime: this.state.lastTime - 1,
},()=>{
// 这样才能正常获取到更改后的状态
if(this.state.lastTime === 0) {
clearInterval(this.timer);
}
});
}, 1000);
}
render() {
return <div>倒计时:{this.state.lastTime}</div>;
}
}

setState的第一个参数也可以写成一个函数,函数的参数表示当前的状态,该函数的返回结果会覆盖(混合)原来的状态,该函数也是异步执行。

使用(第一个参数为函数)这一模式,当多次同步调用setState时,后一个状态的改变会等前一个状态改变完成后执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { Component } from "react";

// 倒计时组件
export default class Tick extends Component {
// 初始化组件
state = {
lastTime: this.props.number,
};
constructor(props) {
super(props);
// // 初始化组件
// this.state = {
// lastTime:this.props.number
// }
this.timer = setInterval(() => {
this.setState({
lastTime: this.state.lastTime - 1,
},()=>{
if(this.state.lastTime === 0) {
clearInterval(this.timer)
}
console.log(this.state.lastTime);
});
this.setState(current=>{
return {
lastTime: current.lastTime - 1,
}
});
}, 1000);
}
render() {
console.log("render")
return <div>倒计时:{this.state.lastTime}</div>;
}
}


// 会先输出render,再输出倒计时。

实践:

  1. 尽量把所有的setState当作是异步的
  2. 永远不要信任setState调用之后的状态
  3. 如果要使用状态改变后的的状态,需要使用回调函数(setState的第二个参数)
  4. 如果新的状态要根据之前的状态进行计算,使用函数的方式改变状态(setState的第一个参数为函数)

React会对异步的setState进行优化,将多次setState进行合并(将多次状态改变后完成后,再统一对state进行改变,然后触发render)