Реализация глобальных постоянных событий сокетов в приложении React / Redux - PullRequest
0 голосов
/ 14 июня 2019

Я создаю приложение для языкового обмена / чата с React / Redux / Socketio, и я натолкнулся на стену.

Я написал простое промежуточное программное обеспечение socketio для redux, чтобы справиться с моими пользовательскими действиями с сокетом, и я использую сокетное соединение глобально. Я добавляю прослушиватели событий на componentDidMount

 componentDidMount() {
    const { id, socketSubscribe, receiveTalksList } = this.props;
    socketSubscribe('sendTalksList', receiveTalksList);
    socketSubscribe('message', messageHandler);
    socketSend('getTalksList', id);
  }

и удаление их в компоненте WillUnmount

  componentWillUnmount() {
    const { socketUnsubscribe } = this.props;
    socketUnsubscribe('sendTalksList');
    socketUnsubscribe('message');
  }

Дело в том, что я хочу иметь возможность прослушивать события сокетов даже после размонтирования компонента. Например, я хочу получать сообщение «message», даже когда я на странице / компоненте профиля пользователя.

Итак, что сразу приходит на ум, «не отписывайтесь от этих событий». Однако в этом случае прослушиватели событий дублируются на каждом componentDidMount.

Чтобы избежать этого дублирования, в моем промежуточном ПО socketio я пытался сделать это

 if (action.type == types.SOCKET_SUBSCRIBE && action.handler) {
        if (socket.listeners(action.event).length > 0 || socket.listeners(action.event).includes(action.handler)) return;
        socket.on(action.event, action.handler);
        return;
      }

Проверка socket.listeners(action.event).includes(action.handler) в основном бессмысленна, потому что каждый раз, когда компонент монтируется, создается новый экземпляр, и поэтому messageHandler является новым функциональным объектом, и невозможно проверить на равенство.

И хотя socket.listeners(action.event).length > 0 работает в том смысле, что он предотвращает повторяющиеся события, я могу прикрепить только один обработчик к событию. Это означает, что другие компоненты не могут подписаться на событие «message».

Единственное, о чем я могу думать, это преобразовать слушателей в строки и выполнить сравнение строк. Что довольно некрасиво и ненадежно. if (socket.listeners(action.event).filter(listener => listener.toString() === action.handler.toString()).length > 0) return;

Есть ли способ зарегистрировать все эти обработчики ТОЛЬКО ОДИН РАЗ? Я думал о создании некоторого элемента типа контейнера / родителя, где он просто регистрирует все события при первой загрузке приложения (или даже регистрирует все обработчики в главном маршрутизаторе), но он должен иметь все ссылки на все обработчики и состояние переменные, которые, вероятно, даже не доступны на данный момент.

Есть идеи?

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