首先了解乙個造成不能立即生效的原因,setstate非同步的原因是因為react的監聽事件為合成事件,state執行過程中會經歷乙個生命週期函式,執行多個setstate會被合併,提公升效能,下面幾種方式可以避免我們的問題:
setstate合適同步何時非同步?
由react控制的事件處理程式,以及生命週期函式呼叫setstate不會同步更新state 。
react控制之外的事件中呼叫setstate是同步更新的。比如原生js繫結的事件,settimeout/setinterval等。
this.setstate();this.setstate();
this.setstate(); //
執行後結果相當於
const count = this
.state.count;
this.setstate();
this.setstate();
this.setstate();
1、傳遞函式()=>,react提供的引數props保證每次都拿到最新的
//第乙個函式呼叫更新state,第二個函式是更新完之後的**。
this.setstate((prevstate, props) =>;
// 獲取stateconsole.log(this.state); // 1
});
2、設定settimeout、setinterval,和事件玄幻有關係
settimeout(fn,0)的含義是,指定某個任務在主線程最早可得的空閒時間執行,也就是說,盡可能早得執行。它在"任務佇列"的尾部新增乙個事件,因此要等到同步任務和"任務佇列"現有的事件都處理完,才會得到執行。
settimeout(() =>;});//
獲取state
console.log(this.state); //
1 }, 0);
3、設定js原生監聽事件addeventlistener
原生事件的呼叫棧就比較簡單了,因為沒有走合成事件的那一大堆,直接觸發click事件,到requestwork
,在requestwork
裡由於expirationtime === sync
的原因,直接走了performsyncwork
去更新,並不像合成事件或鉤子函式中被return,所以當你在原生事件中setstate後,能同步拿到更新後的state值。
handleclick3 = () =>);//某些條件可能獲取不到最新的值
console.log(this
.state);
};componentdidmount()
詳細**如下:
class demo extends react.component ;handleclick0 = () =>);
this.setstate();
this.setstate();
//某些條件可能獲取不到最新的值
console.log(this
.state);
};//
1、把物件改為**函式
handleclick1 = () =>;
});//獲取state
console.log(this.state); //1};
//2、設定settimeout,setinterval
handleclick2 = () =>;
});//獲取state
console.log(this.state); //
1 }, 0);
};//
3、設定原生監聽事件,不同呼叫react的一些生命週期,直接觸發onclick
handleclick3 = () =>);
//某些條件可能獲取不到最新的值
console.log(this
.state);
};componentdidmount()
render() >按鈕0
this.handleclick1()}>按鈕1
this.handleclick1()}>按鈕2
this.handleclick1()}>按鈕3
); }
}
對react setState 的理解
setstate是非同步的,對於這個我們隨便測試一些就知道的,關於為什麼是非同步的可以參考部落格的一些見解。我們翻開react原始碼 version 16.3.2 首先是 setstate部分,看到這裡接受兩個引數partialstate 區域性狀態,限定只有物件和函式可以作為第乙個引數 callb...
react setState 陣列 物件多種方式
this.setstate array.splice 0,1 this.setstate array.splice array.length 1 this.setstate array.splice index,1 this.setstate this.setstate this.setstate ...
立即退出程式
新建乙個類activitycollector作為activity管理器 public class activitycollector public static void removeactivity activty activity public static void finishall 這個管...