在咱們閱讀文檔的時候,大多都說react的setState是異步的,但是它真的是異步的嗎?若是是,那咱們還能夠猜測:那能夠不能夠同步?那何時須要異步,何時須要同步呢?
咱們先來看下react的官方對setSate的說明:react
將setState()認爲是一次請求而不是一次當即執行更新組件的命令。爲了更爲可觀的性能,React可能會推遲它,稍後會一次性更新這些組件。React不會保證在setState以後,可以馬上拿到改變的結果。
一個很經典的例子:異步
// 初始state.count 當前爲 0 componentDidMount(){ this.setState({count: state.count + 1}); console.log(this.state.count) }
若是你熟悉react,你必定知道最後的輸出結果是0,而不是1。性能
咱們再來看一個例子學習
class Demo extends Component { constructor(props) { super(props); this.state = { number: 0 }; } render() { return <button ref="button" onClick={this.onClick.bind(this)}>點我</button>; } componentDidMount() { //手動綁定mousedown事件 this.refs.button.addEventListener( "mousedown", this.onClick.bind(this) ); //setTimeOut setTimeout(this.onClick.bind(this), 1000); } onClick(event) { if (event) { console.log(event.type); } else { console.log("timeout"); } console.log("prev state:", this.state.number); this.setState({ number: this.state.number + 1 }); console.log("next state:", this.state.number); } } export {Demo};
在這個組件中採用3中方法更新statethis
1.在div節點中綁定onClick事件 2.在componentDidMount中手動綁定mousedown事件 3.在componentDidMount中使用setTimeout調用onClick
在點擊組件後,你能夠猜到結果嗎?輸出結果是:code
timeout prev state: 0 next state: 1 mousedown prev state: 1 next state: 2 click prev state: 2 next state: 2
結果彷佛有點出人意料,三種方式只有在div上綁定的onClick事件輸出了能夠證實setState是異步的結果,另外兩種方式顯示setState彷佛是同步的。component
總結:
1.在組件生命週期中或者react事件綁定中,setState是經過異步更新的。
2.在延時的回調或者原生事件綁定的回調中調用setState不必定是異步的。生命週期
這個結果並不說明setState異步執行的說法是錯誤的,更加準確的說法應該是setState不能保證同步執行。事件
我的學習總結,有錯誤的地方歡迎指正٩̋(๑˃́ꇴ˂̀๑)