github上面dan解釋了為什么react setState為什么是異步的。
前提:
首先我們都應該同意如果setState()方法同步re-render在很多情況下是很差的選擇。將setState的改變的效果進入隊列有序,并在某個特定的時間節(jié)點合并性誉,一起刷新state是一個很好的機制领猾。
舉個例子:如果我們給父節(jié)點和子節(jié)點兩個組件最疆,都綁定了點擊事件,當他們要觸發(fā)setState的時候每聪,我們并不希望事件的冒泡,導致子節(jié)點被re-render兩次齿风。我們更希望將父子節(jié)點標記為dirty(臟)組件药薯,在
事件結束之前,一起re-render父子節(jié)點救斑。
下面是dan給出的兩個理由:
1.保證內(nèi)部(數(shù)據(jù))統(tǒng)一
首先童本,我們假定setState是同步的那么:
console.log(this.state.value) // 0
this.setState({ value: this.state.value + 1 });
console.log(this.state.value) // 1
this.setState({ value: this.state.value + 1 });
console.log(this.state.value) // 2
這種只用到了state的情況下,同步setState是可以的脸候。
但是如果有props參與到了傳值穷娱,那么同步setState模式就會有問題,比如我們把
state提升到了父組件绑蔫,利用props將值傳導子組件:
console.log(this.props.value) // 0
this.props.onIncrement();
console.log(this.props.value) // 0
this.props.onIncrement();
console.log(this.props.value) // 0
導致這樣的結果主要原因是:當setState同步改變父節(jié)點state的時候,父節(jié)點傳遞給子節(jié)點的props是不能同步刷新的泵额,原因是上面提到的背景:setState時同步re-render是很差的機制配深,這一點已經(jīng)成為了共識,無法同步re-render就無法同步刷新this.props這就導致了子節(jié)點props數(shù)據(jù)嫁盲,和父節(jié)點state值不一致篓叶,這就破壞了保證內(nèi)部數(shù)據(jù)統(tǒng)一。
2.setState異步更新狀態(tài)使得并發(fā)更新組件成為可能
首先我們在這里討論是否同步刷新state有一個前提那就是我們默認更新節(jié)點是遵循特定的順序的羞秤。但是按默認順序更新組件在以后的react中可能就變了缸托。
在以后的react的更新機制中,我們可能加入setState優(yōu)先級這一概念瘾蛋。
舉個例子:比如你現(xiàn)在正在打字俐镐,那么TextBox組件需要實時的刷新。但是當你在輸入的時候瘦黑,來了一個信息京革,這個時候,可能讓信息延后刷新可能更符合交互幸斥。
異步rendering不僅僅是性能上的優(yōu)化匹摇,而且這可能是react組件模型在發(fā)生的根本性的改變。
當然這個理由甲葬,可能是react發(fā)展的一個方向廊勃,目前還沒有實現(xiàn)。