Как удалить обратный вызов функции стрелки Javascript EventEmiiter

Мой код React продолжает запускать обратные вызовы EventEmitter, которые должны были быть удалены. Когда я проверял свой класс React, который расширяет EventEmiiter, я обнаружил, что обратные вызовы все еще присутствуют в полях Мероприятия, хотя удалитьслушатель уже вызывался для этих обратных вызовов.

Я подозреваю, что это происходит потому, что я добавляю обратные вызовы в EventEmitter как стрелочные функции, но когда я их удаляю, я этого не делаю. Удаление их как стрелочных функций не работает. В моем коде ниже FirebaseStore расширяет EventEmitter:

  _onFirebaseChange() {
    this.setState({
      refId: this.getRefId()
    });
  }

  componentDidMount() {
    FirebaseStore.addChangeListener(() => this._onFirebaseChange());
  }

  componentWillUnmount() {
    FirebaseStore.removeChangeListener(this._onFirebaseChange);
  }

Мне нужно использовать стрелочные функции, потому что для событий изменения (_onFirebaseChange) требуется доступ к это.состояние.

Когда я смотрю на свой источник из инструментов разработчика Chrome, мне трудно определить, относятся ли addChangeListener и удалитьChangleListener к одному и тому же обратному вызову:

key: 'componentDidMount',
value: function componentDidMount() {
  var _this2 = this;

  _FirebaseStore2.default.addChangeListener(function () {
    return _this2._onFirebaseChange();
  });
}
},{
key: 'componentWillUnmount',
value: function componentWillUnmount() {
  _FirebaseStore2.default.removeChangeListener(this._onFirebaseChange);
}}

Вот соответствующий код из магазина Firebase:

addChangeListener(callback) {
    this.on(FIREBASE_CHANGE_EVENT, callback);
  }

  removeChangeListener(callback) {
    this.removeListener(FIREBASE_CHANGE_EVENT, callback);
  }
}

Можно было бы исправить это с помощью замыкания, но я думаю, что это перебор.

()=>foo() отличается от foo - это не имеет ничего общего с реакцией, поскольку эти функции просто не равны, и поэтому remove не может найти ту, которую вы хотите удалить. Есть много похожих постов, которые решают это для других событий в JavaScript, возможно, кто-то найдет хороший дубликат, чтобы отреагировать так.
Alexei Levenkov 09.02.2019 21:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
110
2

Ответы 2

Обновите метод componentDidMount.

componentDidMount() {
   FirebaseStore.addChangeListener(this._onFirebaseChange);
}

Функция должна быть привязана напрямую.

Это не сработает — без модификации кода выше — из-за того, что мне нужен доступ к это.состояние из функции _onFirebaseChange.

kashiB 10.02.2019 00:17

Это было простое исправление, которое я должен был поймать раньше. Опубликованное Алекси решение закрытия также сработало бы, но все, что ему не хватало, — это привязать * _onFirebaseChange* к это в конструкторе.

Итак, в конструкторе моего класса React я добавил эту строку:

this._onFirebaseChange = this._onFirebaseChange.bind(this);

Затем моя функция компонентдидмаунт смогла ссылаться на тот же обратный вызов, что и компонентWillUnmount, а также могла получить доступ к это.состояние.

  componentDidMount() {
    FirebaseStore.addChangeListener(this._onFirebaseChange);
  }

  componentWillUnmount() {
    FirebaseStore.removeChangeListener(this._onFirebaseChange);
  }

Другие вопросы по теме