反应:如何在AddListener()中使用setState?

时间:2019-01-23 08:03:51

标签: reactjs listener bind typeerror setstate

我有一个方法,可以在您单击按钮之前,对尚不存在的数据调用addListener。但是,当我尝试在状态内设置数据时,出现以下错误:

  

TypeError:this.setState不是函数

我尝试像这样绑定我的dataHandler:

this.dataHandler = this.dataHandler.bind(this)

但是它仍然返回此错误。我在这里忘记了什么?

constructor(props){
    super(props)
    this.state = {
        selActive: 4,
        loaded: false,
        mapInfo: ''
    }
    this.onScriptLoad = this.onScriptLoad.bind(this)
    this.dataHandler = this.dataHandler.bind(this)
}

dataHandler = (getJson) => {
    fetch(getJson)
        .then(response => response.json())
        .then(featureCollection => 
            dataLayer = map.data.addGeoJson(featureCollection)
        );
    map.data.addListener('mouseover', function(event) {
        map.data.revertStyle();
        map.data.overrideStyle(event.feature, {fillColor: 'blue'});
        // THIS IS WHERE I ADD MY SETSTATE. 
        // HOWEVER, THIS RETURNS AN ERROR ON HOVER
        this.setState({mapInfo: event.feature.countryNL})
    });
}

3 个答案:

答案 0 :(得分:3)

在JavaScript this中,总是指我们正在执行的函数的“所有者”,或更确切地说,指函数是方法的对象。 请改用箭头功能。 箭头函数没有自己的this/super/arguments绑定。它从其父词法范围继承它们。

map.data.addListener('mouseover', (event) => {
    map.data.revertStyle();
    map.data.overrideStyle(event.feature, {fillColor: 'blue'});
    // THIS IS WHERE I ADD MY SETSTATE. 
    // HOWEVER, THIS RETURNS AN ERROR ON HOVER
    this.setState({mapInfo: event.feature.countryNL})
});

参考:

答案 1 :(得分:1)

普通函数中的

this引用全局对象或当前实例(如果通过new调用)。但是,箭头函数内部的this是从外部范围捕获的。因此,this回调中的addListener引用了全局对象(window)。要解决此问题,您可以使用以下选项:

  • 使用箭头功能:

    map.data.addListener('mouseover', (event) => {
        map.data.revertStyle();
        map.data.overrideStyle(event.feature, {fillColor: 'blue'});
        // THIS IS WHERE I ADD MY SETSTATE. 
        // HOWEVER, THIS RETURNS AN ERROR ON HOVER
       this.setState({mapInfo: event.feature.countryNL})
    });
    
  • 使用bound function

    map.data.addListener('mouseover', function (event) {
        map.data.revertStyle();
        map.data.overrideStyle(event.feature, {fillColor: 'blue'});
        // THIS IS WHERE I ADD MY SETSTATE. 
        // HOWEVER, THIS RETURNS AN ERROR ON HOVER
       this.setState({mapInfo: event.feature.countryNL})
    }.bind(this));
    

答案 2 :(得分:1)

首先,我不建议您使用匿名函数设置为事件侦听器,因为在这种情况下,您将无法removeEventListener或类似的东西(可能是因为不清楚, map是什么)。

第二件事是您不应该绑定dataHandler,因为它已经是一个箭头函数,所以this上下文中的dataHandler不会有问题。您应该绑定的东西是您的手动事件列表器。因此,结果代码应如下所示:

constructor(props){
    super(props)
    this.state = {
        selActive: 4,
        loaded: false,
        mapInfo: ''
    }
    this.onScriptLoad = this.onScriptLoad.bind(this)
    this.dataHandler = this.dataHandler.bind(this)
    this.handleMouseOver = this.handleMouseOver.bind(this)
}

dataHandler = (getJson) => {
    fetch(getJson)
        .then(response => response.json())
        .then(featureCollection => 
            dataLayer = map.data.addGeoJson(featureCollection)
        );
    map.data.addListener('mouseover', this.handleMouseOver);
}

handleMouseOver(event) {
    map.data.revertStyle();
    map.data.overrideStyle(event.feature, {fillColor: 'blue'});
    this.setState({mapInfo: event.feature.countryNL})
}

,或者使用箭头功能自动绑定:

constructor(props){
    super(props)
    this.state = {
        selActive: 4,
        loaded: false,
        mapInfo: ''
    }
    this.onScriptLoad = this.onScriptLoad.bind(this)
    this.dataHandler = this.dataHandler.bind(this)
}

dataHandler = (getJson) => {
    fetch(getJson)
        .then(response => response.json())
        .then(featureCollection => 
            dataLayer = map.data.addGeoJson(featureCollection)
        );
    map.data.addListener('mouseover', this.handleMouseOver);
}

handleMouseOver = (event) => {
    map.data.revertStyle();
    map.data.overrideStyle(event.feature, {fillColor: 'blue'});
    this.setState({mapInfo: event.feature.countryNL})
}

希望,这会对您有所帮助! :)