setState(API)的非同步和同步問題
阿新 • • 發佈:2021-06-28
在react中,想要改變state內部狀態,需要使用setState進行修改,如果只是修改state的部分屬性,則不會影響其他的屬性,這個只是合併並不是覆蓋。
this.setState(),該方法接收兩種引數:物件或函式(理解物件形式是函式形式的簡寫)。
- 物件:this.setState({key:value})。
- 函式:接收兩個函式,第一個函式接受兩個引數,第一個是當前state,第二個是當前props,該函式返回一個物件,和直接傳遞物件引數是一樣的,就是要修改的state;第二個函式引數是state改變後觸發的回撥
在此還需要注意的是,setState有非同步更新和同步更新兩種形式,那麼什麼時候會同步更新,什麼時候會非同步更新呢?
React控制之外的事件中呼叫setState是同步更新的。比如原生js繫結的事件,setTimeout/setInterval等。
大部分開發中用到的都是React封裝的事件,比如onChange、onClick、onTouchMove等,這些事件處理程式中的setState都是非同步處理的。
總結:setState同步非同步和呼叫環境,上下文有關。
import React,{Component,createRef} from "react"; class SetStateAsync extends Component { state = { num:0 } btnRef = createRef(); //更新狀態的兩種方式: //1、物件形式 addNum = (params)=>{ console.log(params); this.setState({ num:this.state.num+1 }) } //2、函式形式 // addNum = (params)=>{ // console.log(params); // this.setState((state,props)=>{// console.log(state,props,"什麼引數!!!"); // return { // num:this.state.num + 1 // } // },()=>{ // //獲取非同步的最新修改state的值。 // console.log(this.state.num); // }) // } //問題:setState(API)同步非同步問題!!! /* 通過react控制的呼叫是非同步的。 react控制:即react二次封裝的事件。 通過原生呼叫setState是同步的。 同步如下: */ componentDidMount(){ this.btnRef.current.addEventListener("click",()=>{ console.log("原生方法執行了!!!!"); this.setState({ num:this.state.num+1 }); console.log(this.state.num,"同步的setState更新狀態!!!"); }) } render(){ return ( <> <p>同步非同步更新state狀態</p> <p>數量:{this.state.num}</p> <button ref={this.btnRef} onClick={()=>this.addNum("改變num數量!!!")} className='btn'>點我+1</button> </> ) } } export default SetStateAsync;