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> ); } }
试试吧!