React setState需要注意的地方
函数内部多次调用setState
,会将所有的setState
操作进行合并,如果有修改到相同的属性,谁在最后执行谁,例如下面调用3次setState
,count
初始值是0
,依次修改count
的值,分别加1,加2,加3,最终count
的值会被修改为3,而不是6
import React from 'react'
class Counter extends React.Component {
constructor(props) {
super(props)
this.state = {
count: 0,
}
}
clickHandle = () => {
this.setState({
count: this.state.count + 1
})
this.setState({
count: this.state.count + 2
})
this.setState({
count: this.state.count + 3
})
}
render () {
console.log('render');
return (
<div>
<h1 id="title">计数器:{this.state.count}</h1>
<button onClick={this.clickHandle}>+1</button>
</div>
)
}
}
export default Counter
如果我们想要结果为6,就是都执行的话,需要给setState
传入一个函数,函数的入参分别是最新的state
和最新的props
,可以进行解构,得到自己想要的值,下面的setState
执行了3次,每次都拿到了最新的state
,因此count
最终会被修改为6
// ...
clickHandle = () => {
this.setState((state, props) => {
console.log(state); // {count: 0}
return {
count: state.count + 1
}
})
this.setState((state, props) => {
console.log(state); // {count: 1}
return {
count: state.count + 2
}
})
this.setState(({count}, props) => {
console.log(count); // 3
return {
count: state.count + 2
}
})
}
我们设置了setState
,怎么拿到最新的值呢?直接在setState
后面获取行不行?答案是不行,因为setState
是异步的,因此每次拿到的都是初始值,也就是0
// ...
clickHandle = () => {
this.setState((state, props) => {
console.log(state); // {count: 0}
return {
count: state.count + 1
}
})
// 这里获取到的值是0,因为setState是异步的
console.log(this.state.count) // 0
}
那有什么方法可以拿到修改后的值呢?我们可以给setState
传入第二个参数,是一个函数,可以拿到setState
修改后的值,但是请注意,是所有setState合并执行后的值!
// ...
clickHandle = () => {
this.setState((state, props) => {
return {
count: state.count + 1
}
}, () => {
console.log('更新后的状态:', this.state.count); // 2
})
this.setState((state, props) => {
return {
count: state.count + 1
}
}, () => {
console.log('更新后的状态:', this.state.count); // 2
})
}
除了上面的方式使得我们可以同步设置state
,还有其他一些方法,但是我们只推荐使用上面的方法,下面的方法都不建议使用
定时器
// ... clickHandle = () => { setTimeout(() => { this.setState({ count: this.state.count + 1 }) console.log(this.state.count); // 这里获取到的就是修改后的count 1 }, 0) setTimeout(() => { this.setState({ count: this.state.count + 1 }) console.log(this.state.count); // 这里获取到的就是修改后的count 2 }, 0) }
原生事件中修改状态
// ... clickHandle = () => { this.setState({ count: this.state.count + 1 }) console.log(this.state.count); // 这里获取到的就是修改后的count 1 this.setState({ count: this.state.count + 1 }) console.log(this.state.count); // 这里获取到的就是修改后的count 2 } componentDidMount() { this.btnRef.addEventListener('click', this.clickHandle, false) }
使用
async
/await
(不规范,不建议使用)clickHandle = async () => { await this.setState({ count: this.state.count + 1 }) console.log(this.state.count); // 这里获取到的就是修改后的count 1 await this.setState({ count: this.state.count + 1 }) console.log(this.state.count); // 这里获取到的就是修改后的count 2 }
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com