目录
问题导入
export default class App extends Component {
state = {
n: 1
}
hClick = () => {
this.setState({n: 100})
console.log(this.state.n) // 1
console.log(document.getElementById('span').innerHTML) // 这会打印 1
}
render () {
return (
<div>
<button onClick={this.hClick}>click</button>
<span id="span">
n: {this.state.n}
</span>
</div>
)
}
}
setState的特点
-
setState({对象})是异步的
setState调用之后,并不会立即去修改state的值,也不会立即去更新dom
-
多次调用setState({对象})会合并,再统一触发一次render()
-
在componentDidUpdate, render 中调用setState()会导致死循环
setState进阶-完整格式
掌握setState箭头函数的语法,解决多次调用依赖的问题
setState的第二个参数
格式1
this.setState({}[,回调函数])
回调函数是可选的,它的作用是:当本轮setState生效(state更新,页面ui更新)之后,会调用回调函数
格式2
this.setState((上一状态) => {
return 新状态
}[,回调函数])
内容
-
推荐:使用
setState((preState) => {})
语法 -
参数preState: React.js 会把上一个
setState
的结果传入这个函数
this.setState((preState) => {
return {
count: preState.count + 1
}
})
console.log(this.state.count) // 1
示例1
state = {
n: 1
}
hClick = () => {
this.setState( preState => ({ n: preState.n + 1 }))
this.setState( preState => ({ n: preState.n + 2 }))
this.setState( preState => ({ n: preState.n + 3 }))
console.log(this.state.n) // 1
}
// 页面上的n会是多少?
// 页面上 n 是 7
这种语法依旧是异步的,但是state可以获取到最新的状态,适用于需要调用多次setState
示例2
state = {
n: 1
}
hClick = () => {
this.setState( preState => ({ n: preState.n + 1 }), ()=>{console.log(this.state.n)})
this.setState( preState => ({ n: preState.n + 2 }), ()=>{console.log(this.state.n)})
this.setState( preState => ({ n: preState.n + 3 }), ()=>{console.log(this.state.n)})
}
// 1. 页面上的n会是多少?
// 7
// 2. 三个console.log会输出什么?
// 7 7 7
这种语法依旧是异步的,但是state可以获取到最新的状态,适用于需要调用多次setState
setState进阶-同步or异步
setState本身并不是一个异步(setTime, setInterval, ajax,Promise.then.....)方法,其之所以会表现出一种异步的形式,是因为react框架本身的性能优化机制
在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用 setState 不会同步更新 this.state,除此之外的setState调用会同步执行this.state。
所谓“除此之外”,指的是绕过React通过 addEventListener
直接添加的事件处理函数,还有通过setTimeout
|| setInterval
产生的异步调用。
简单一点说:
-
经过React 处理(事件回调,钩子函数)中的setState是
异步更新
-
没有经过React处理(通过
addEventListener
||setTimeout
/setInterval
)中的setState是同步更新
。
总结:
setState是同步的方法,但是react为了性能优化,所以setState在react的事件中表现得像异步。
参考链接: