На моей практике лучшим методом работой с различными EventEmitter/PubSub механизмами - это подписыватель возвращающий отписыватель. То есть некая функция, которая на основе своих аргументов организует подписку и возвращает функцию без аргументов, которая при вызове отменит подписку, отпишет от события и т.д.
Пример из личной библиотеки:
import {curry} from 'ramda';
export const subscribe = curry((target: EventTarget, eventName: string, handler: EventListenerOrEventListenerObject): (() => void) => {
target.addEventListener(eventName, handler);
return () => target.removeEventListener(eventName, handler);
});
Если убрать ramda и typescript, то останется такое:
export const subscribe = (target, eventName, handler) => {
target.addEventListener(eventName, handler);
return () => target.removeEventListener(eventName, handler);
};
Суть: subscribe при вызове подпишет DOM объект target на событие eventName с функцией handler и вернет функцию без аргументов, которая при вызове отпишет DOM объект target от события eventName для функции handler
В Вашем случае будет так:
const curry = (i) => (e) => changeCountry(e, i);
const unsubscribe = subscribe(button, 'click', curry(i));
// когда подписка больше не нужна, просто вызываем unsubscribe()