import React,{Component} from 'react';
class Search extends Component{
constructor(props){
super(props);
this.state = {name:''};
}
handleSearch(){
console.log(this); // null
console.log(this.state.name);// 报错
}
render(){
return (
);
}
}
请问代码中的打印log那里的this为什么是null?handleSearch是button中调用的,怎么也不可能是null啊?应该是button这个dom吧。
另外,在页面中直接这样写:
var handleClick = function (event) {
console.log(this); // 不是null是
}
document.getElementById('foo').addEventListener('click', handleClick);
document.getElementById('foo').click();
我知道怎么解决。我只想知道react中this为什么不是dom而是null??
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
更新
原来楼主问的是为什么
this是null,而不是DOM或者window之类的东西。。。嗯,我也很好奇,所以我查了一下源码,跳来跳去好晕。。。先说一下,按照你的写法,在
development环境下,是null。在production环境下,是undefined。简单的说一下原因:
babel编译出来的代码都会添加"use strict",变成严格模式。而你知道,如果使用严格模式,而没有手动绑定this的话,那么this不是window,而是undefined。而如果使用bind(null)的话,this就是null。然后,由于
react使用的是事件代理,并不是原生的事件,所以他的调用方法并不会像原生那样绑定对象的DOM。最后,经过源码的观察来看,事件的
callback在存入的时候,并没有做任何绑定。在调用的时候,在production下,没有做什么绑定。而在development下,绑定了null。(或者这么说不准确,事件的回调在添加的时候,使用proxyMethod做了一层封装,而在里面是用了apply(this, arguments)来调用原来的回调函数。而在production下,没有对proxyMethod做什么绑定,所以上面apply时候的this是undefined。而在development下,绑定了null,所以上面的this是null)不知道你明白没。。。
原答案
四种解决方法,任何一种都可以解决
像@hyy1115那样在
constructor里面绑定一下在
<button onClick={this.handleSearch.bind(this)}>搜搜</button>绑定这个样子调用:
<button onClick={()=>{ this.handleSearch()}}>搜搜</button>使用箭头函数可以解决这个问题
React开发组在决定实现组件对ES6类的支持时取消了自动绑定,具体可以看这里
动动手指绑定一下
因为你这是jsx语法写的,实际上最终编译出来的可是 :
由此可见这个事件函数只是引用了当前指针,但是这个click函数运行的上下文环境并不在这个Search组件内部,所以js引擎找不到this,最终会出错,解决方法都很完善,就不多嘴了
使用createClass 方式创建的组件的 函数式自动绑定的
使用es6 则需要手动绑定
在constructor中 clickHandler= this.clickHandler.bind(this)
箭头函数
es7双冒号绑定 在组件中 onClick = {::this.clickHandler}
你说的第二种通过addEventListener绑定事件的方法是原生事件绑定,和第一种不一样,第一种是React的三种合成事件绑定的一种,使用合成事件绑定的一个点就是要手动绑定,绑定方式上述回答已经说的很详细了。