How can I interact with the API if the states in redux are supposed to be immutable?

So, in this application, I am using the MediaRecorder api ( https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder ). I am trying to use React-Redux as a base for a site. Below is a simplified version of my reducer to illustrate my question:

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

      

So, I read that the reduction state should be immutable. However, I need to stop the media recorder somehow so that it doesn't record any recordings. Is it state.stop()

ok?

+3


source to share


1 answer


No, this is definitely a bad role model.

In the Redux FAQ, your state in the store should only be JS serializable data . This way, you can keep track of the value of the type {playing : true}

in the store, but you really shouldn't be holding an instance of the class.

The "correct" way to do this is to have the React component that wraps around the imperative MediaRecorder API get the values ​​from the Redux store as props and call the MediaRecorder functions in their React lifecycles, for example componentWillReceiveProps

I show some examples of how this do in my blog post Declaratively Rendering Earth in 3D, Part 2: Cesium Control with React , and I have links to other similar articles in the React / Redux Reference List section .



A quick example might look like this:

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

      

+5


source







All Articles