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> ); } }
试试吧!
网友评论文明上网理性发言 已有1人参与
发表评论:
评论列表