React开发应用:了解下setState同步和异步问题。
setState 只在合成事件和钩子函数中是"异步"的,在原生事件和 setTimeout 中都是同步的。
合成事件:就是react 在组件中的onClick等都是属于它自定义的合成事件
原生事件:比如通过addeventListener添加的,dom中的原生事件
以下为同步拿到数据:
在setState中的回调函数中拿到
this.setState({
count: this.state.count + 1},()=>{
console.log(this.state.count)
})
在setTimeOut中拿到:
setTimeout(()=>{
this.setState({count:this.state.count})
console.log(this.state.count)
},0)
在原生事件中修改状态:
state = {
count:0};componentDidMount() {
document.body.addEventListener('click', this.changeVal, false);}changeVal = () => {
this.setState({
number: 1
})
console.log(this.state.count)}
在React中,由React控制的事件处理函数,如onClick, onChange等,setState是异步的。
import React, { Component } from 'react';
export default class Input extends Component {
constructor(props) {
super(props);
this.state={
name: 'hello'
}
}
_onChange(e) {
this.setState({
name:' world'
})
console.log(this.state.name); //hello
}
render () {
return (
<div className='cp'>
<input className='cp-input' value={this.state.name} onChange={this._onChange.bind(this)} type="text"/>
</div>
);
}
}
在原生JS监听的事件中,如addEventListener, setState是同步的。
import React, { Component } from 'react';
export default class Input extends Component {
constructor(props) {
super(props);
this.state={
name: 'hello'
}
}
_onChange(e) {
// do something
}
componentDidMount() {
let input = document.querySelector('.cp-input');
input.addEventListener('click', ()=>{
this.setState({
name:' world'
})
console.log(this.state.name); //world
})
}
render () {
return (
<div className='cp'>
<input className='cp-input' value={this.state.name} onChange={this._onChange.bind(this)} type="text"/>
</div>
);
}
}
在setTimeout中,setStatet是同步的。
import React, { Component } from 'react';
export default class Input extends Component {
constructor(props) {
super(props);
this.state={
name: 'hello'
}
}
_onChange(e) {
// do something
}
componentDidMount() {
setTimeout(()=>{
this.setState({
name:' world'
})
console.log(this.state.name); //world
}, 1000)
}
render () {
return (
<div className='cp'>
<input className='cp-input' value={this.state.name} onChange={this._onChange.bind(this)} type="text"/>
</div>
);
}
}
试试吧!