react組件中事件處理的幾種寫法号醉,幾種寫法的區(qū)別反症,bind(this)傳自定義的參數
一、在React元素綁定事件要注意的兩點
- 在React中事件的命名要采用駝峰命名法畔派,而不是原生dom中的小寫铅碍,如:onclick要寫成onClick, onchange 要寫成onChange
- 響應事件的函數要以對象的形式賦值线椰,而不是以dom字符串的形式胞谈,如:
//在 dom中:
<button onclick="clickMe()">不服點我</button>
//在React中
<button onClick={clickButton}>不服點我</button> //clickButton是一個函數
注意:React的事件是合成事件,并不是原生的dom事件憨愉,在dom中可以通過返回false來阻止事件的默認行為烦绳,但是在react中必須顯示調用事件對象的e.preventDefault來阻止事件的默認行為,除了這一點之外爵嗅,和原生的事件并無差別
二、在React中事件處理函數主要的三中寫法笨蚁,不同的寫法解決this指向問題的方式也不同睹晒,性能也有差異趟庄,具體如下:
1. 使用es6的箭頭函數
class MyComponent extends React.Component{
constructor(){
super(props);
this.state = {
number:0
}
}
render(){
<button onClick={(e)=>{console.log(this.state.number);}}>不服點我</button>
}
}
分析,此時this指向的是函數定義時所在的對象伪很,所以this總是指向當前組件的實例戚啥,不足是當前的組件邏輯比較復雜時,把組件的邏輯寫在{}內會導致render的臃腫锉试,不容易比較直觀的看出UI的結構猫十,同時代碼的可讀性也不會很好,解決方法為把邏輯封裝為組件的一個方法呆盖,然后在函數中調用這個方法:
class MyComponent extends React.Component{
constructor(){
super(props);
this.state = {
number:0
}
}
handleClick(e){
const number = ++this.state.number;
this.setState({
number
});
};
render(){
<button onClick={(e)=>this.handleClick(e);}>不服點我</button>
}
注意拖云,直接在render中定義事件處理函數的最大的問題就是,每次render調用的時候都會創(chuàng)建一個新的事件處理函數应又,給組件帶來額外的開銷宙项,當組件的層級越低,開銷就越大株扛,組件上的任何上一層級組件的變化都會觸發(fā)這個組件的render方法(一般可以忽略)尤筐。
2.使用組件的方法
直接將組件的方法賦值給這個事件的元素,同時在構造函數中將這個方法的this綁定到當前對象洞就,如:
class MyComponent extends React.Component{
constructor(){
super(props);
this.state = {
number:0
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
const number = ++this.state.number;
this.setState({
number
});
};
render(){
<button on click={this.handleClick}>不服點我</button>
}
這種方法的好處是每次渲染都不會重新創(chuàng)建一個回調函數盆繁,沒有額外的性能損失;
但是旬蟋,如果在一個組件中有很多的事件函數時油昂,這種在構造函數中綁定this的方法就會比較繁瑣,所以還可以直接在給事件屬性直接賦值時綁定this咖为;
class MyComponent extends React.Component{
constructor(){
super(props);
this.state = {
number: 0
}
}
handleClick(e){
const number = ++this.state.number;
this.setState({
number
});
}
render(){
<div>{this.state.number}</div>
<button onClick={this.handleClick.bind(this)}>點我</button>
}
}
分析:
(1)缺點: 此方法在每次render時都會重新創(chuàng)建一個函數秕狰,在性能上有所損失;
(2)優(yōu)點: 事件處理函數需要傳參數時躁染,這個方法比較好鸣哀,看下面的例子
class MyComponent extends React.Component{
constructor(){
super(props);
this.state = {
list: [1, 2, 3, 4, 5],
current: 1
}
}
//每點擊一項,將點擊項設置為當前項吞彤,所以需要將點擊項作為參數傳遞
handleClick(item, e){
this.setState({
current: item
});
}
render(){
let { list } = this.state;
return (
<ul>
{
(!!list && list.length>0) && list.map((listItem, index)=>{
return <li onClick={this.handleClick.bind(this, listItem)}>{listItem}</li>
})
}
</ul>
)
}
}
3. 屬性初始化語法(property initializer syntax)
使用es7的屬性初始化語法會自動為class中的定義的方法綁定this我衬,例如:
class MyComponent extends React.Component{
constructor(){
super(props);
this.state = {
number: 0
}
}
handleClick = (e)=>{
const number = ++this.state.number;
this.setState({
number
});
}
render(){
<div>{this.state.number}</div>
<button onClick={this.handleClick}>點我</button>
}
}
優(yōu)點:此種方法既不用擔心在構造函數中綁定this,非常繁瑣饰恕;
也不用擔心在渲染時重復生成函數挠羔,造成性能問題
這個還處在實驗性階段,默認不支持埋嵌,但是官方的腳手架 creat-react-app 默認支持破加;如果你要是想在項目中使用,你可以在項目中引入babel 的 transform-class-properties 插件獲取這個特性的支持雹嗦。
以上為react事件處理的三種方式以及this問題的全部內容范舀,如有不當合是,歡迎指正