前言
接下來讓我們進入新的章節:漫談React。
本篇文章主要講React事件系統和表單操作。
正文
一:事件系統
1.react的事件系統
react事件系統符合W3school標準,不存在任何IE相容性問題,並且與原生的瀏覽器事件一樣有同樣的API介面。同樣支援事件的冒泡機制,我們可以使用stopPropagation()和preventDefault()來終止它。
所有的事件都自動繫結到最外層。如果需要訪問原生事件物件,可以使用nativeEvent屬性。
2.合成事件
(1)事件委派
react把所有事件繫結到結構的最外層,使用一個同意的事件監聽器,這個事件監聽器上維持了一個對映來儲存所有元件內部的事件監聽和處理函式。
(2)自動繫結
在react元件中,每個方法的上下文都會指向該元件的例項,即自動繫結this為當前元件。但是在使用ES6 classes或者純函式時這種自動繫結就不復存在,需要手動實現this的繫結。
(3)繫結方法
3-1:bind方法:可以幫助我們繫結事件處理完器內的this,並且可以向事件處理器中傳入引數,比如:
import React,{Component} from `react`
class App extends Component{
handleClick(e,arg){
console.log(e,log);
}
render(){
return <button onClick={this.handleClick.bind(this,`test`)}>Test</button>;
}
}
3-2構造器內宣告(推薦):在元件的構造器內完成對事件的繫結。
class App extends Component{
handleClick(e){
console.log(e);
this.handleClick=this.handleClick.bind(this);
}
render(){
return <button onClick={this.handleClick.bind(this,`test`)}>Test</button>;
}
}
3-3箭頭函式:它自動繫結了定義此函式作用域的this。
class App extends Component{
const handleClick= (e)=>{
console.log(e);
}
render(){
return <button onClick={this.handleClick.bind(this,`test`)}>Test</button>;
}
}或
import React,{Component} from `react`
class App extends Component{
handleClick(e,arg){
console.log(e,log);
}
render(){
return <button onClick={()=>this.handleClick()}>Test</button>;
}
}
3.原生事件
componenDidMount會在元件已經完成安裝並且在瀏覽器存在真實的 DOM後呼叫,此時我們就可以完成對原生事件的繫結。
import React,{Component} from `react`
class nativeEventDemo extends Component{
componentDidMount(){
this.refs.button.addEventListener(`click`,e=>{
handleClick(e);
})
}
handleClick(e){
console.log(e);
}
componentWillUnmount(){
this.refs.button.removeEventListener(`click`);
}
render(){
return <button ref = `button`>Test</button>
}
}
注意:在react中使用DOM原生事件時,一定要在元件解除安裝時手動移除,否則可能出現記憶體洩漏問題。
4.混合事件
我們無法在元件中將事件繫結到元件範圍之外的區域,只能使用原生事件來實現。
但是,儘量在React中混用合成事件和原生DOM事件:用reactEvent.nativeEvent.stopPropagatoin()來阻止事件冒泡是不行的。組織React事件冒泡的行為只適用於React合成系統中,且沒辦法阻止原生事件冒泡。反之,在原生事件中阻止事件冒泡,卻可以阻止React事件的傳播。
對於無法使用React的合成事件系統的場景,我們還需要使用原生事件來完成。