我有一个方法,可以在您单击按钮之前,对尚不存在的数据调用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})
});
}
答案 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})
});
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})
}
希望,这会对您有所帮助! :)