2017-05-27 53 views
3

所以在這個應用程序中,我使用的是MediaRecorder API(https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder)。我正在嘗試使用React-Redux作爲網站的框架。以下是我的減速器的簡化版本來說明我的問題:如果redux中的狀態應該是不可變的,我將如何與有狀態的API交互?

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

因此,我讀到了redux狀態應該是不可變的。但是,我必須以某種方式停止媒體記錄器,以便它停止錄製內容。這是state.stop()好嗎?

回答

5

不,這絕對是一個不好的模式。

根據Redux FAQ,your store state should only be plain serializable JS data。因此,您可能會在商店中跟蹤{playing : true}這樣的值,但實際上不應該在其中保留類實例。

「正確」的方式做,這將有一個陣營組成部分,圍繞勢在必行MediaRecorder API包,從終極版店作爲道具接收值,並在其陣營的生命週期方法調用MediaRecorder功能,如componentWillReceiveProps。我在我的博客文章Declaratively Rendering Earth in 3D, Part 2: Controlling Cesium with React中顯示了一些如何做到這一點的示例,並且鏈接到了我的React/Redux links listReact Component Patterns#Wrapping Non-React Code部分中的其他類似文章。

一個簡單的例子可能看起來像:

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

非常感謝你。我想知道這是否真的需要成爲一個組件,因爲它可能只是一個提供媒體記錄器作爲服務的JavaScript類。 (我在角度方面有更多的經驗,所以我通過服務模式會是一個好主意嗎?不確定是否有反應) –

+0

使其成爲React組件的最大原因是利用React的生命週期方法來控制MediaRecorder實例, React-Redux處理對商店的訂閱。你當然可以用普通的JS類做同樣的方法,但是你必須實現商店訂閱邏輯和生命週期處理。 – markerikson

相關問題