1、对象式的setState
setState(stateChange,[callback])
stateChange
为状态改变的对象(该对象可以体现出状态的更改)callback
是可选的回调函数,它在状态更新完毕后,界面也更新后(render调用后)才被调用
import React, { Component } from 'react'
export default class Demo extends Compontent {
//初始化状态
state = { count: 0 }
//绑定方法
add = () => {
// 1.获取count值
const {count} = this.state
// 2.更新状态(setState是同步的方法,但是引起更新的状态却是异步的)
this.setState({count: count+1}, ()=>{
console.log('render调用后调用:', this.state.count) // render调用后调用:1
})
console.log('输出其实是更新前的值:', this.state.count) // 输出其实是更新前的值:0
}
//渲染组件
render () {
return (
<div>
<h3>当前值为: {this.state.count}</h3>
<button onClink={this.add}>+1</button>
</div>
)
}
}
注意:
- setState是同步的方法,但是引起更新的状态却是异步的
- 如果要查看变化后的状态,可以使用callback函数(可选),是在状态更新完毕、界面也更新后(render调用后)才被调用。
2、函数式的setState
setState(updater,[callback])
updater
为返回stateChange
对象的函数updater
可以接受到state
和props
callback
是可选的回调函数,它在状态更新完毕后,界面也更新后(render调用后)才被调用
import React, { Component } from 'react'
export default class Demo extends Compontent {
state = { count: 0 }
add = () => {
// 函数式
this.setState(state => ({count: state.count+1}) )
}
render () {
return (
<div>
<h3>当前值为: {this.state.count}</h3>
<button onClink={this.add}>+1</button>
</div>
)
}
}
总结
- 对象式setState是函数式setState的简写方式(语法糖)
- 使用原则:
(1).如果新状态不依赖与原状态 ===> 使用对象方式
(2).如果新状态依赖与原状态(需要用到state) ===> 使用函数方式
(3).如果需要在 setState() 执行后获取最新的状态数据,要在callback函数中读取
相关面试题:
# 调用setState之后,发生了什么?
- 代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
- 经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
- 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异(用diff算法),然后根据差异对界面进行最小化重渲染;(diff算法使React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。)
# React中的setState是同步执行还是异步执行?如果是异步的?怎么拿到执行后的state?
- setState 并不能保证是同步的,在生命周期函数和合成事件中是异步的,在原生事件和 setTimeout 中是同步的。
# 为什么建议传递给setState函数的参数是回调函数而不是对象?
- 因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。
# 传入setState函数的第二个参数的作用是什么
- 该函数会在
setState
函数调用完成并且组件开始重渲染的时候被调用,我们可以用该函数来监听渲染是否完成。