Создание нового объекта Howler Object в Action Creators и отправка действий на события - PullRequest
0 голосов
/ 09 ноября 2019

Итак, я пытаюсь создать аудиоплеер React.js + Redux. Я использую библиотеку Howler.js для обработки аудио из API. Я отправляю действия с кнопок управления плеером и с другого компонента, такого как компонент списка дорожек. Когда пользователь нажимает на дорожку в списке, я отправляю объект дорожки в Player Reducer. Здесь я создаю новый объект Howl, который работает , но здесь есть некоторые проблемы:

  • Поскольку Howler извлекает данные из API, это асинхронная задача, и это нешаблон. Я знаю это, но здесь я не запускаю события из Howler, поэтому он работает, но он немного глючит.
  • Я не могу использовать триггеры событий, потому что это будет асинхронно и это плохая практика для отправки действийот редуктора.

Что бы я хотел:

  • Создание нового объекта-ревула в моем Создателе действий.
  • Использованиесобытие инициирует, например, onload () или onloaderror (), чтобы отправить другое действие, чтобы сообщить игроку, что Howler готов воспроизвести песню или если произошла ошибка.

Код:

Action Creator

export const PLAYER_INITIALIZE = 'PLAYER_INITIALIZE'
export const initialize = () => {
    return {
        type: PLAYER_INITIALIZE,
    }
}

export const PLAYER_SET_TRACK = 'PLAYER_SET_TRACK'
export const setTrack = (trackId) => {
    return {
        type: PLAYER_SET_TRACK,
    }
}

export const PLAYER_PLAY_TRACK = 'PLAYER_PLAY_TRACK'
export const playTrack = () => {
    return {
        type: PLAYER_PLAY_TRACK,
    }
}

Редуктор

function PlayerReducer(state = initialPlayerState, action) {
    switch (action.type) {

        case PlayerActions.PLAYER_SET_TRACK:
            if (state.audioObj.state() != 'unloaded')
                state.audioObj.unload();
            return {
                ...state,
                audioObj: new Howl({
                    src: API.API_STREAM_TRACK + action.trackId,
                    html5: true,
                    preload: true,
                    onload: () => {
                        console.log("Track loaded succesfully.");
                    },
                    onloaderror: (id, err) => {
                        console.error("Load Error : " + err);
                    }
                }),
                trackMetadata: action.trackMetadata
            };

        case PlayerActions.PLAYER_PLAY_TRACK:
            state.audioObj.play();
            return {
                ...state,
                isPlaying: true,
            };

      [...]

Моя идея состоит в том, чтобы воплотить Гоулера следующим образом:

new Howler({
    [ ... some options ],
    onload: () => {
        dispatch({
            type: PLAYER_LOAD_SUCCESS
        });
    },
    onloaderror: () => {
        dispatch({
            type: PLAYER_LOAD_ERROR
        });
    }
});

Как я могу отредактировать этот код, чтобы правильно создать новый объект Howl в Action Creator и передать его игроку на каждой дорожке, которую я хочу прослушать?

Можете привести пример?

Спасибо.

1 Ответ

0 голосов
/ 09 ноября 2019

Вы можете добавить redux-thunk в свое приложение и затем иметь возможность отправлять несколько действий от одного создателя действия. После добавления redux-thunk ваше действие может выглядеть следующим образом:

export const setTrack = (trackId) => {
  (dispatch, getState) => {
    const { audioObj } = getState();
    if (audioObj != null) {
      audioObj.unload();
    }

    dispatch({
      audioObj:  new Howler({
          [ ... some options ],
          onload: () => {
              dispatch({
                  type: PLAYER_LOAD_SUCCESS
              });
          },
          onloaderror: () => {
              dispatch({
                  type: PLAYER_LOAD_ERROR
              });
          }
      }),
      type: PLAYER_SET_TRACK
  });
}

вы можете таким же образом перенести вашу другую асинхронную работу и работу Howler в создателей действий и заставить ваш редуктор заниматься только хранением информации.

...