Реакция: Как использовать setState в AddListener ()? - PullRequest
0 голосов
/ 23 января 2019

У меня есть метод, который вызывает 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 голосов
/ 23 января 2019

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));
    
0 голосов
/ 23 января 2019

Прежде всего, я не рекомендую вам использовать анонимные функции для установки в качестве прослушивателей событий, потому что в этом случае вы не сможете 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})
}

Надеюсь, это поможет вам! :)

0 голосов
/ 23 января 2019

В 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})
});

Ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...