如何在React按钮onClick中同时调用ReactMediaRecorder内置方法与自定义函数
问题原因
你外层自定义的startRecording、stopRecording方法,和render回调参数里组件提供的内置同名方法是完全独立的两个函数,你之前直接把外层自定义方法传给Controls组件,全程没有调用组件内置的录制控制方法,所以原生录制功能自然不会触发。
解决方案
只需要在你的自定义逻辑执行前后,主动调用组件提供的内置方法即可,两种实现方式可选:
方式1:内联组合(代码更简洁)
直接在给Controls传参时拼接自定义逻辑和内置方法调用:
function RecordAudio(props) { const isVideo = false; // 补充const避免污染全局变量 return ( <ReactMediaRecorder audio render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => ( <Row> {status === 'recording' ? ( <AudioPreview stream={previewStream} /> ) : ( <audio src={mediaBlobUrl} controls autoPlay /> )} <Controls status={status} startRecording={(evt) => { // 你的自定义逻辑 console.log('start streaming'); fetch('/api/stream/start', { method: 'post' }).then((response) => { console.log('stream requested'); }); // 调用组件内置的启动录制方法 startRecording(); // 如果你需要等接口返回后再启动录制,把startRecording()移到上面的then回调里即可 }} stopRecording={(evt) => { // 你的自定义逻辑 console.log('stop streaming'); fetch('/api/stream/stop', { method: 'post' }).then((response) => { audioStreamer.stopStreaming(); console.log('streaming ended'); }); // 调用组件内置的停止录制方法 stopRecording(); }} mediaBlobUrl={mediaBlobUrl} /> </Row> )} /> ); }
方式2:外层封装方法(逻辑复用性更高)
如果你的自定义逻辑需要在多处复用,可以单独封装成高阶函数,传入内置方法生成最终的事件处理函数:
function RecordAudio(props) { const isVideo = false; // 封装启动逻辑 const wrapStart = (originalStart) => (evt) => { console.log('start streaming'); fetch('/api/stream/start', { method: 'post' }).then((response) => { console.log('stream requested'); }); originalStart(); }; // 封装停止逻辑 const wrapStop = (originalStop) => (evt) => { console.log('stop streaming'); fetch('/api/stream/stop', { method: 'post' }).then((response) => { audioStreamer.stopStreaming(); console.log('streaming ended'); }); originalStop(); }; return ( <ReactMediaRecorder audio render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => ( <Row> {status === 'recording' ? ( <AudioPreview stream={previewStream} /> ) : ( <audio src={mediaBlobUrl} controls autoPlay /> )} <Controls status={status} startRecording={wrapStart(startRecording)} stopRecording={wrapStop(stopRecording)} mediaBlobUrl={mediaBlobUrl} /> </Row> )} /> ); }
内容的提问来源于stack exchange,提问作者jdog
相关产品推荐
相关产品推荐

