鍍金池/ 問(wèn)答/HTML5  Python  HTML/ 關(guān)于react輸入框的onChange事件的觸發(fā)問(wèn)題

關(guān)于react輸入框的onChange事件的觸發(fā)問(wèn)題

最近在學(xué)習(xí)react.js的過(guò)程中遇到了一點(diǎn)問(wèn)題,先上代碼圖:

clipboard.png

這個(gè)例子里面的input我給他添加了一個(gè)onChange事件事實(shí)改變state值來(lái),并將state綁定在input的value上動(dòng)態(tài)更新. 同時(shí)我在事件里面分別實(shí)時(shí)console除了state值和input的value值,問(wèn)題就出現(xiàn)了...如下圖

clipboard.png
這個(gè)是輸出state值的結(jié)果,問(wèn)題在于每次輸出的不是實(shí)時(shí)的值,而是上一次的值,相當(dāng)于慢了一拍.

clipboard.png
這個(gè)是直接根據(jù)事件的event事件獲取到input取的實(shí)時(shí)value,這張圖就沒(méi)有這個(gè)問(wèn)題.

所以我有一點(diǎn)不明白,為什么setState執(zhí)行完畢之后,react的這一輪事務(wù)應(yīng)該已經(jīng)結(jié)束了呀,組件的state已經(jīng)被更新了呀,為什么還會(huì)console出上一輪的值呢?望大佬解答.....

ps: 題外話: 為什么要給input的value綁定上state,我覺得不綁定也是可以的啊,用戶可以正常輸入,只需要一個(gè)onChange事件更新state就好了...

回答
編輯回答
護(hù)她命

setState() 是一個(gè)異步操作,后面的 console.log() 執(zhí)行的時(shí)候, state 還沒(méi)更新完,所以輸出的是之前的值。

2018年6月16日 05:54
編輯回答
巫婆

setState 并不會(huì)立即刷新狀態(tài)樹,它還要合并新舊狀態(tài)并掃描虛擬DOM樹找出受影響的節(jié)點(diǎn)(比如你題外話里說(shuō)的 value=this.state.value)然后去更新節(jié)點(diǎn)上的UI部分,這是一件很耗時(shí)(相對(duì)而言)的事,所以會(huì)等一個(gè)時(shí)機(jī)去做批量更新,在這之前 state 并不會(huì)被改變。

深入研究React setState的工作機(jī)制 - DanceOnBeat - 博客園

至于為什么給 value 綁定 state 上的值,是因?yàn)?react雙向綁定 這個(gè)打通 ModelView 的大殺器啊,你不用再自己去監(jiān)聽某個(gè)變量是否變化然后做界面上的修改。

2017年5月27日 17:53
編輯回答
心上人

handleChange(e){

let that = this;
setTimeout(() => {
    that.setState({
        value: e.target.value
    })
}, 0);

}
用setTimeout進(jìn)行二次渲染即可
如果想要知道原理,得看官方源碼中的onCollectCommon,不過(guò)效果也是一樣的,即使是修改官方源碼也是必須得進(jìn)行二次渲染

2017年2月3日 18:01
編輯回答
舊言

setState作為一個(gè)異步操作,是支持回調(diào)的~

this.setState({value: event.target.value}, () => console.log(this.state.value))
2018年8月2日 07:13
編輯回答
逗婦惱

setState是異步操作的,你不能馬上拿到state的指,可以用回調(diào)去拿
this.setState({value: event.target.value}, () => console.log(this.state.value))

2017年10月18日 07:02
編輯回答
不歸路

這樣并沒(méi)有問(wèn)題,你最后提交的state肯定是和你輸入的是一樣的

2017年6月30日 06:44