如果redux中的状态应该是不可变的,我将如何与有状态API交互?

Jas*_* Yu 3 redux react-redux

所以在这个应用程序中,我使用的是MediaRecorder api(https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder).我试图使用React-Redux作为网站的框架.以下是我的reducer的简化版本来说明我的问题:

(state = {}, action) => {
    switch(action.type){
        case "START_RECORDING":
            return new MediaRecorder(...).start();
        case "STOP_RECORDING":
            state.stop(); <--- is this ok?
            return {};
    }
    return state;
})
Run Code Online (Sandbox Code Playgroud)

所以我读到redux状态应该是不可变的.但是,我必须以某种方式停止媒体录制器,以便它停止录制内容.这样state.stop() 好吗?

mar*_*son 5

不,这绝对是一个糟糕的模式.

根据Redux FAQ,您的商店状态应该只是简单的可序列化JS数据.因此,您可能会跟踪{playing : true}商店中的值,但实际上您不应该在其中保留类实例.

执行此操作的"正确"方法是使用React组件包装命令式MediaRecorder API,从Redux存储中接收值作为props,并在其React生命周期方法中调用MediaRecorder函数,如componentWillReceiveProps.我在我的博客文章中展示了如何做到这一点的一些例子,在3D中声明渲染地球,第2部分:使用React控制Cesium,并且我在React组件模式的其他类似文章的链接#Radpping Non-React Code部分的React/Redux链接列表.

一个简单的示例可能如下所示:

class MediaRecorderWrapper extends React.Component {
    componentDidMount() {
        this.mediaRecorder = new MediaRecorder();

        if(this.props.playing) {
            this.mediaRecorder.start();
        }
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.playing !== this.props.playing) {
            if(nextProps.playing) {
                this.mediaRecorder.start();
            }
            else {
                this.mediaRecorder.stop();
            }
        }
    }
}

const mapState = (state) => {
    return {
        playing : state.playing
    };
}

export default connect(mapState)(MediaRecorderWrapper);
Run Code Online (Sandbox Code Playgroud)