组件状态
组件状态:组件可以自行维护的数据
组件状态仅在类组件有效
状态(state):本质上是类组件的一个属性,是一个对象
组件状态初始化
- 在constructor中初始化
1 2 3 4 5 6 7
| constructor(props){ super(props); this.state = { lastTime:this.props.number } }
|
- 直接初始化,使用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.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.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>; } }
|
实践:
- 尽量把所有的setState当作是异步的
- 永远不要信任setState调用之后的状态
- 如果要使用状态改变后的的状态,需要使用回调函数(setState的第二个参数)
- 如果新的状态要根据之前的状态进行计算,使用函数的方式改变状态(setState的第一个参数为函数)
React会对异步的setState进行优化,将多次setState进行合并(将多次状态改变后完成后,再统一对state进行改变,然后触发render)