vue button onclick绑定_React组件的事件绑定

React组件事件绑定

关于this

一个问题

假设有这样一个问题,求输出语句的打印

var obj = {
  fn:function(){
    console.log(this)
  }
}
var outFn = obj.fn
obj.fn() //this为obj
outFn()  //this为window
8c89b205a95e5ab5ef9046a06bea7fb0.png

为什么会出现这样的状况?

函数调用

函数调用有三种方式(暂时不讨论apply)

fn(p1,p2)
obj.fn(p1,p2)
obj.call(context,p1,p2)

其中第三种方式才是真正的函数调用方式

在第三种方式中 context是指this的指向

前两种调用方式只是语法糖 所以他们只是第三种方式的简写

那么我们就可以翻译前两种写法

fn.call(null,p1,p2)
obj.fn(obj,p1,p2)

由于浏览器默认当context为null/undefined时,this会指向window 所以fn()的this为window

代码转换

还是上述题目

var obj = {
  fn:function(){
    console.log(this)
  }
}
var outFn = obj.fn
obj.fn() 
outFn()  

把这个题目的所有函数调用用call代替

var obj = {
  fn:function(){
    console.log(this)
  }
}
var outFn = obj.fn
obj.fn.call(obj)  //this就是obj
outFn.call(null)  //因为context为null,所以this为window

一些题目

var a = {
  name:'里面的name',
  sayName:function(){
    console.log('name:',this.name);
  }
}
var name = '外面的name'
function sayName(){
   var s = a.sayName;
   s();
   a.sayName();
   (a.sayName)();
   (b = a.sayName)();
}
sayName()

尝试使用代码翻译

var a = {
  name:'里面的name',
  sayName:function(){
    console.log('name:',this.name);
  }
}
var name = '外面的name'
function sayName(){
   var s = a.sayName();
   s.call(null); 
   a.sayName(a);
   (a.sayName).call(a);
   b.call(null);
}
sayName()
3e946710771176f22095544743751937.png
var length = 10
function fn(){
  console.log(this.length)
}
var obj = {
  length:5,
  method:function(){
    fn()
    arguments[0]()
  }
}
obj.method(fn,1)

尝试使用代码转换

var length = 10
function fn(){
  console.log(this.length)
}
var obj = {
  length:5,
  method:function(){
    fn.call(null)  // this.length === 10
    // arguments.0是错误语法 这里只是为了方便理解
    arguments.0.call(argument)  // this.length === argument.length === 2
  }
}
obj.method.call(obj,fn,1)  //this === obj && argument === [fn,1]
1c7c779cd41869b41955f587c89cb98b.png

箭头函数的this

箭头函数本身是不支持this和arguments的

如果看到箭头函数有this 就把箭头函数里的this当作外面的this

例如

class A{
  constructor(){
    this.fn = ()=>{console.log(this)}
  }
}

var a = new A()
a.fn()
var b = a.fn
b()
6f44d08e624c95bb50e287c30181358f.png

事件绑定的this

btn.addEventListener('click',function handle(){
  console.log(this)
})

上述代码可以被翻译为

btn.onclick = function handle(){
  console.log(this)
}

用call做代码翻译

btn.onclick.call(btn)  //this === btn
4d30dbf8637992373a018098ad85f348.png

React事件绑定的方法

还是+1的例子 我们要给button绑定click事件,使得能够实现+1

class A extends React.Component{
  constructor(){
    super()
    this.state = {
      n:0
    }
  }
  addN(){
    this.setState({n:this.state.n+1})
  }
  render(){
    return (
      <div>
        {n}<button onClick=·····>n+1button>div>
    )
  }
}

问题是❓:省略号内的内容如何写

this.addN()}>n+1</button>
  • 这种方法是一种万无一失的方法
this.addN}>n+1</button>
  • 这种方法会使得addN内部的this变成window
  • 当事件被点击的时候,会调用button.onClick.call(null)
  • 所以this会变成window
2e61db940f61592dfbdc700f56e225a4.png
this.addN.bind(this)}>n+1</button>
  • 通过强制绑定this.不会使得addN内部的this变成window
class A extends React.Component{
  constructor(){
    super()
    ···
    this._addN = ()=> this.addN()
  }
}
this._addN}>n+1</button>
  1. 由于4还需要重新起名 所以我们做一个改进
class A extends React.Component{
  constructor(){
    super()
    ···
    this.addN = ()=> this.setState({n:this.state.n+1})
  }
}
this.addN}>n+1</button>
  1. 最终答案

一个语法糖 使得我们不需要把事件处理函数写在构造函数内

class A extends React.Component{
  constructor(){
    super()
    ···
  }
  addN = ()=> this.setState({n:this.state.n+1})
}
this.addN}>n+1</button>

mindSet

相比于Vue,React令人感觉对于新手更有劝退性。React能把人逼疯,但是疯过之后会让人涅槃重生,加油 继续React之旅

Goodbye

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值