在动作创建者中实例化一个新的咆哮对象,并在事件上调度动作

问题描述 投票:0回答:1

所以我正在尝试构建一个React.js + Redux音频播放器。我正在使用Howler.js库来处理来自API的音频。我从播放器控制按钮和其他组件(如曲目列表组件)调度动作。当用户单击lis中的轨道时,我正在向Tracker Reducer分配一个轨道对象。我在这里实例化了一个新的How叫对象,它但是这里有一些问题:

  • 因为Howler正在从API提取数据,所以这是异步任务,并且是反模式。我知道,但是在这里我不会触发来自咆哮的事件,因此它可以正常工作,但是有点问题。
  • 我不能使用事件触发器,因为它将是异步的,并且从Reducer调度动作是很糟糕的做法。

我想要的是:

  • 在我的动作创建者中实例化一个新的咆哮对象。
  • [使用事件触发器,例如onload()或onloaderror()来调度其他操作,以告知播放器Howler准备播放歌曲或出现错误。

代码:

动作创建者

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

如何编辑此代码以在Action Creator中正确创建一个新的Howl对象,并将其传递给我想听的每条轨道上的播放器?

你能给我一个例子吗?

谢谢。

reactjs react-redux action howler.js
1个回答
0
投票

您可以将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
  });
}

您可以通过这种方式将其他异步和咆哮工作转移到动作创建者中,并使减速器仅关注存储信息。

© www.soinside.com 2019 - 2024. All rights reserved.