Redux每个实例一个商店相互通信

时间:2017-01-01 13:48:36

标签: javascript reactjs redux react-redux

我有多个音频播放器组件实例。我在每个实例中使用一个商店,例如以下链接:https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400How to create one store per instance in Redux?

这对于一次更新单个音频播放器非常有用。 问题是每个音频播放器需要能够以某种方式在某些动作上相互通信(即,当一个音频播放器开始播放时,其他音频播放器需要暂停)。如何在每个实例的单个商店中执行此操作?目前我还没有看到如何与其他商店实例进行沟通。

我尝试在其中只有一个商店和多个实例但是然后状态在所有音频播放器之间共享,这不是我想要的某些属性(即当一个音频播放器开始播放时它们都开始播放)

他们有什么方法可以拥有这样的州属性吗?

每个实例音频播放器的唯一状态属性:

{
    paused: false,
    mp3: ""
}

所有音频播放器之间的共享状态属性:

{
    globalPause: true, //Pause all other audio player instances that have this set to true
    globalVolume: true  //Modify volume of all other audio player instances that have this set to true
}

AudioPlayer:

class AudioPlayer extends React.Component {
    render() {
        return (
            <Player className="default">
                <Gui>
                {//Other Components here}
                </Gui>             
                <BrowserUnsupported /> 
            </Player>
        );
    }
}

AudioPlayer.options = {
    selector: "audio-player",
    muted: true,
    autoplay: false,
    mp3: //Mp3 url,
};

export default AudioPlayer;

AudioPlayerTwo:

class AudioPlayerTwo extends React.Component {
    render() {
        return (
            <Player className="default">
                <Gui>
                {//Other Components here}
                </Gui>             
                <BrowserUnsupported /> 
            </Player>
        );
    }
}

AudioPlayerTwo.options = {
    selector: "audio-player-two",
    muted: true,
    autoplay: false,
    mp3: //Mp3 url,
};

export default AudioPlayer;

指数:

createPlayer(AudioPlayer);
createPlayer(AudioPlayerTwo);

createPlayer:

const mapStateToProps = (state) => ({
    ...state.Player, 
});

const mapDispatchToProps = (dispatch) => ({Player: bindActionCreators(PlayerActions, dispatch)});

export default createPlayer = (WrappedComponent) => {
    WrappedComponent = connect(mapStateToProps, mapDispatchToProps)(WrappedComponent);

    const store = createStore(reducer, {
        Player: defaultValues
    });

    ReactDOM.render(
    <Provider store={store}>
        <WrappedComponent />
    </Provider>,
    document.getElementById(WrappedComponent.options.selector));
}

动作(其中一些具有相同的格式):

export const play = (time) ({
    type: "PLAY",
    time
});

export const volume = (volume) ({
    type: "VOLUME",
    volume
});

减速机:

const play = (state, action) => {
    if(state.srcSet) {
        return updateOption(state, {
            paused: false,
            newTime: !isNaN(action.time) ? action.time : state.currentTime 
        });
    }
}

const volume = (state, action) => updateOption(state, {
    volume: limitValue(action.volume, 0, 1)
});

const updateOption = (existingObject, newValues) => ({
    ...existingObject, 
    ...newValues
});

export default (state={}, action) => {
    switch (action.type) {        
        case "PLAY": 
            return play(state, action);
        case "VOLUME":
            return volume(state, action);
        default:
            return state;
    }
}

1 个答案:

答案 0 :(得分:-1)

你需要使用redux中间件,我的建议是redux-saga和pub /子库,如postal.js。

基本上你想要的是一个发布动作的中间件,其他中间件正在监听(订阅)。因此,例如,如果您在一个玩家上玩,则中间件发布此事件,并且所有其他玩家正在通过酒吧/子库进行收听,当他们看到此消息时,他们可以通过“停止”。对当地的redux商店采取行动。