React事件系統
事件處理程序通過
合成事件(SyntheticEvent)
的實例傳遞,SyntheticEvent
是瀏覽器原生事件跨瀏覽器的封裝
。SyntheticEvent 和瀏覽器原生事件一樣有 stopPropagation()、preventDefault() 接口,而且這些接口跨瀏覽器兼容。
- 原生事件
document.querySelector('xxx').addEventListener('click', () => {
console.log(event);
})
// 輸出1:windowEvent ====> chorme
// 輸出2: undefined ====> Firefox
可以看出event參數不加的話,有的瀏覽器會兼容,像火狐就不兼容,因此需要在事件handler中寫
document.querySelector('xxx').addEventListener('click', event => {
event = event || window.event;
event.stopPropagation();
event.preventDefault();
})
如果不寫event而是在函數中傳了某種參數,如果是chorme還好,會給你補充一個window.event,某些不支持的瀏覽器就會把你的參數當event了,當然會報錯了;
- React的事件
- 0.12版本之前可以使用在event handler(onclick = xxx.bind(this))函數中使用
return false
來代替stopPropagation 和 preventDefault, 目前已經被移除,請不要使用。 - 使用
合成事件(SyntheticEvent)
(類似jquery的$event)是對各種瀏覽器兼容的event相關封裝,目前支持以下屬性- boolean bubbles
- boolean cancelable
- DOMEventTarget currentTarget
- boolean defaultPrevented
- Number eventPhase
- boolean isTrusted
- DOMEvent nativeEvent
- void preventDefault()
- void stopPropagation()
- DOMEventTarget target
- Date timeStamp
- String type
- 默認所有事件都在冒泡階段被觸發,如果想使用事件捕獲有兩種方法
- 使用原生addEventListener('click', handler, true)
第三個參數給true
- 使用onClickCapture = xxx.bind(this);
- 使用原生addEventListener('click', handler, true)
- 傳統開發方式在元素較多時建議使用
事件委托 / 事件代理
方式在父級進行代理事件,但React獨特的事件處理系統會先把所有事件處理函數都收集到父級,再根據組件進行派發,因此無需特意寫事件代理函數,即使一個列表有一萬個組件元構成,onClick函數也可以寫在組件元中。 - 事件池
event在React是一個虛擬對象,在事件被收集后到父級元素中時,虛擬對象會被合并,在該事件處理的回調后屬性就沒用了,如果用setState這種異步方法調用的話就沒有用了。
function onClick(event) {
console.log(event); // =>無效的對象
console.log(event.type); // => "click"
var eventType = event.type; // => "click"
setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);
this.setState({clickEvent: event}); // 不起作用.this.state.clickEvent 將只包含空值.
this.setState({eventType: event.type}); // 您依然可以導出事件屬性
}
如果您想以一個異步的方式來訪問事件屬性,您應該對事件調用event.persist()。這將從事件池中取出合成的事件,并允許該事件的引用,使用戶的代碼被保留。