今天使用React時遇到一個警告:javascript
Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property
target
on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See
https://fb.me/react-event-poo... for more information.
查看文檔解釋:java
The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.SyntheticEvent 對象是經過合併獲得的。 這意味着在事件回調被調用後,SyntheticEvent 對象將被重用而且全部屬性都將被取消。這是出於性能緣由。所以,您沒法以異步方式訪問該事件。react
意思就是說我訪問event.target時處於異步操做中。個人代碼是:app
handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => { this.setState((prevState) => ({ collection: { title: event.target.value, content: prevState.content } })); }
看了不少遍沒發現哪裏有異步操做,沒辦法只好加event.persist()
先解決掉警告:異步
handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => { event.persist(); this.setState((prevState) => ({ collection: { title: event.target.value, content: prevState.content } })); }
可是,我忽然回想起setState
並不保證是同步的:async
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately.
setState() does not always immediately update the component. It may batch or defer the update until later.把setState看成是請求更新組件,而不是當即更新組件。爲了性能,React會延遲更新,會把多個組件的更新放在一次操做裏。React不保證state的改變會馬上發生。
setState並不老是當即更新組件。它可能會推後至批量更新。函數
因此,在個人這段代碼中顯然setState是異步的,由於Event Polling咱們不能在setState的更新函數中訪問event變量。既然找到了緣由,解決方法就有了:性能
不要在setState的更新函數中訪問event
變量:this
handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => { const val = event.target.value; this.setState((prevState) => ({ collection: { title: val, content: prevState.content } })); }
或者若是不須要prevState的話:spa
handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => { this.setState({ collection: { title: event.target.value, content: this.state.content } }); }