摘要:假設現在最后仍然會是,不是所以不能依賴來計算未來狀態。原理可以參考這篇很簡潔易懂的文章其他情景,如上面的情景,或這樣用綁定函數脫離了的控制,不知道如何進行,就會是同步的。
state
state的存在是為了動態改變組件,比如根據不同的用戶操作和網絡請求,來重新渲染組件。
setState()是React給我們的一個API,用來改變或定義state。
setState()的批量操作(batching)在一個事件handler函數中,不管setState()被調用多少次,他們也會在函數執行結束以后,被歸結為一次重新渲染, 可以優化性能, 這個等到最后一起執行的行為被稱為batching。
所以在函數內的setState()是有序的,如果要更改同一個state key,最后被調用的總會覆蓋之前的。
因為batching的存在,所以這樣的代碼會和期待有出入。
//假設現在this.state.value = 0; function eventHandler(){ this.setState({value:this.state.value + 1}); this.setState({value:this.state.value + 1}); this.setState({value:this.state.value + 1}); } //最后this.state.value仍然會是1,不是3;
所以不能依賴this.state來計算未來狀態。如果想實現這樣的效果,應該傳一個函數給setState。這個函數有兩個參數,第一個為previous state,第二個為props。這里的例子和props無關,只需要第一個參數,所以要達到效果,代碼是這樣
// 假設 this.state = { value: 0 }; function eventHandler(){ this.setState((state) => ({ value: state.value + 1})); this.setState((state) => ({ value: state.value + 1})); this.setState((state) => ({ value: state.value + 1})); } //現在this.state.value === 3;
到這里我們得到結論,setState是異步執行的。
如React文檔所說:
"setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains."
所以當更新state,然后想打印state的時候,應該使用回調。
this.setState({key: val},()=>console.log(this.state));所以setState總是異步的,嗎?
當setState()不在事件Handler函數中,如在使用ajax的時候,這種batching的異步表現又不會發生。
promise.then(() => { // 不在事件函數中,所以setState立刻執行 this.setState({a: true}); // 重新渲染 {a: true, b: false } this.setState({b: true}); // 重新渲染 {a: true, b: true } });同步異步要分情況來看: 1. React事件函數使用,像這樣用最常用的形式綁定函數
constructor(props){ ... this.onClick = this.onClick.bind(this); } onClick(){ this.setState({key:val}); } render(){ return(}
這里batching發生,異步表現,是因為這種常規情景下React “知道”什么時候退出該事件,什么時候進行Batch Update。原理可以參考這篇很簡潔易懂的文章
2.其他情景,如上面的ajax情景,或這樣用addEventListener綁定函數componentDidMount(){ document.querySelector("#btn").addEventListener("click,this.onClick); } render(){ return(} }
脫離了React的控制,React不知道如何進行Batch Update,setState()就會是同步的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101984.html
摘要:根本原因在于,并不是真正意義上的異步操作,它只是模擬了異步的行為。而合成事件和生命周期函數中,是受控制的,其會將設置為,從而走的是類似異步的那一套。總結此處總結是直接引用了只在合成事件和鉤子函數中是異步的,在原生事件和中都是同步的。 如何使用setState 在 React 日常的使用中,一個很重要的點就是,不要直接去修改 state。例如:this.state.count = 1是無...
摘要:正文在回復中表示為什么是異步的,這并沒有一個明顯的答案,每種方案都有它的權衡。需要注意的是,異步更新是有可能實現這種設想的前提。 前言 不知道大家有沒有過這個疑問,React 中 setState() 為什么是異步的?我一度認為 setState() 是同步的,知道它是異步的之后很是困惑,甚至期待 React 能出一個 setStateSync() 之類的 API。同樣有此疑問的還有 ...
摘要:我們可以為元素添加屬性然后在回調函數中接受該元素在樹中的句柄,該值會作為回調函數的第一個參數返回。使用最常見的用法就是傳入一個對象。單向數據流,比較有序,有便于管理,它隨著視圖庫的開發而被概念化。 面試中問框架,經常會問到一些原理性的東西,明明一直在用,也知道怎么用, 但面試時卻答不上來,也是挺尷尬的,就干脆把react相關的問題查了下資料,再按自己的理解整理了下這些答案。 reac...
摘要:簡單的舉下例子如等生命周期以及的事件即為異步更新,這里不顯示具體代碼。因為只有當父組件后才傳給子組件,那么如果要變成同步的,就需要放棄。 前言 在看React的官方文檔的時候, 發現了這么一句話,State Updates May Be Asynchronous,于是查詢了一波資料, 最后歸納成以下3個問題 setState為什么要異步更新,它是怎么做的? setState什么時候會...
摘要:的批量更新優化也是建立在異步合成事件鉤子函數之上的,在原生事件和中不會批量更新,在異步中如果對同一個值進行多次,的批量更新策略會對其進行覆蓋,取最后一次的執行,如果是同時多個不同的值,在更新時會對其進行合并批量更新。 api解析: setState(updater, [callback]) updater: 更新數據 FUNCTION/OBJECT callback: 更新成功后的回...
閱讀 4675·2021-09-22 16:06
閱讀 2074·2021-09-22 15:22
閱讀 1410·2019-08-30 15:54
閱讀 2512·2019-08-30 15:44
閱讀 2341·2019-08-29 16:31
閱讀 2010·2019-08-29 16:26
閱讀 2328·2019-08-29 12:41
閱讀 731·2019-08-29 12:22