在react中,批改状态如果间接应用this.state,不会引起组件的从新渲染,须要通过 this.setState来对组件的属性进行批改。

1、this.setState的两种定义形式

定义初始状态

state = { count: 0 },

如果此时有一个按钮,点击按钮让计数加1,咱们能够有两种写法

(1)传递对象 this.setState({ count: this.state.count + 1})(2)传递函数 this.setState((state, props) => ({ count: count + 1}))

2、setState的两种形式有什么不同?

如果变更的state的值须要依赖于上一次的state的值,这种状况就须要用到函数的模式,比方以下这种状况

addCount(){    this.setState({ count: this.state.count + 1})    this.setState({ count: this.state.count + 1})    this.setState({ count: this.state.count + 1})}

此时只会执行一次+1的操作,因为在React外部,会将屡次setState合并操作,新的state由 Object.assgin({}, {count: 0},  { count: 1}) 合并所得,以上赋值会执行三次,但因为count的值没有更新,所以最终执行的后果只+1,如果setState的赋值是函数,那状况就不一样了

addCount(){    this.setState((state, props) => ({ count: count + 1}))    this.setState((state, props) => ({ count: count + 1}))    this.setState((state, props) => ({ count: count + 1}))}

这样的操作会失去+3的成果,因为React会进行判断,如果传入的是函数,那么将执行此函数,此时count的值就曾经被批改了

3、setState是同步还是异步的?

☆☆☆☆☆ 是异步的

(1) 即咱们通过this.setState批改了状态之后,在它的下一行输入state的值并不会失去新的值

(2) 为什么是异步?
有两个起因,一是提高效率,每次批改state的值都会造成render的从新渲染,将屡次批改state的值合并对立更新能够进步性能;二是render的更新会晚一些,如果render中有子组件,子组件的props依赖于父组件的state,props和state就不能保持一致

(3) 如何获取异步时的state值?
① 在setState的回调函数中

this.setState({     count: this.state.count + 1}},     ()=>{ console.log(this.state.count)})

② 在componentDidUpdate中获取

componentDidUpdate(){    console.log(this.state.count)}

☆☆☆☆☆ 是同步的

(1) 即咱们通过this.setState批改状态之后,在它的下一行输入state是新的值

(2) 什么场景下是同步的?
① 原生js获取dom元素,并绑定事件

<button id="addBtn">点我+1</button>componentDidMount(){     const addBtn = document.getElementById('addBtn')     changeBtn.addEventListener('click',()=>{             this.setState({ count:  this.state.count + 1})             console.log(this.state.message)     })}

② 计时器 setTimeout

<button onClick={ e => this.addOne() }>点我+1</button>addOne(){setTimeout(()=>{ this.setState({ count:  this.state.count + 1 })  console.log(this.state.count ) },0)}