You need to enable JavaScript to run this app. 如何将React Hooks版摄像头录制代码改写为可复用类组件
优惠活动
大模型
产品
解决方案
定价
更多

如何将React Hooks版摄像头录制代码改写为可复用类组件

改写完成的可复用摄像头录制类组件

核心映射规则

从函数组件 Hooks 逻辑迁移到类组件的对应关系:

  • 原useRef(null)创建的持久化引用,替换为构造函数内用React.createRef()初始化的实例属性
  • 原useState维护的响应式状态,迁移到类的this.state中,所有状态更新统一使用this.setState()触发重渲染
  • 原useCallback包裹的事件处理函数,替换为类的实例方法,在构造函数中显式绑定this指向,避免执行时上下文丢失

注意:类组件中禁止直接修改this.state的属性值,这类操作不会触发组件重渲染。

完整组件代码

import React from "react";
import Webcam from "react-webcam";

export default class WebcamStreamCapture extends React.Component {
  constructor(props) {
    super(props);
    // 初始化DOM引用,等价于原函数组件的两个useRef
    this.webcamRef = React.createRef();
    this.mediaRecorderRef = React.createRef();
    // 初始化状态,等价于原函数组件的两个useState
    this.state = {
      capturing: false,
      recordedChunks: []
    };
    // 绑定实例方法的this指向
    this.handleStartCaptureClick = this.handleStartCaptureClick.bind(this);
    this.handleDataAvailable = this.handleDataAvailable.bind(this);
    this.handleStopCaptureClick = this.handleStopCaptureClick.bind(this);
    this.handleDownload = this.handleDownload.bind(this);
  }

  handleStartCaptureClick() {
    this.setState({ capturing: true });
    // 初始化媒体录制器
    this.mediaRecorderRef.current = new MediaRecorder(this.webcamRef.current.stream, {
      mimeType: "video/webm"
    });
    // 绑定录制数据回调
    this.mediaRecorderRef.current.addEventListener(
      "dataavailable",
      this.handleDataAvailable
    );
    this.mediaRecorderRef.current.start();
    // 触发父组件录制开始回调
    if (typeof this.props.onRecordingStart === "function") {
      this.props.onRecordingStart();
    }
  }

  handleDataAvailable({ data }) {
    // 收集录制分片
    if (data.size > 0) {
      this.setState((prevState) => ({
        recordedChunks: [...prevState.recordedChunks, data]
      }));
    }
  }

  handleStopCaptureClick() {
    this.mediaRecorderRef.current.stop();
    this.setState({ capturing: false });
  }

  handleDownload() {
    const { recordedChunks } = this.state;
    if (!recordedChunks.length) return;
    // 生成录制视频Blob
    const videoBlob = new Blob(recordedChunks, {
      type: "video/webm"
    });
    // 将生成的Blob透传给父组件做自定义处理
    if (typeof this.props.onDataReady === "function") {
      this.props.onDataReady(videoBlob);
    }
    // 内置下载逻辑,可根据业务需要移除
    const url = URL.createObjectURL(videoBlob);
    const downloadLink = document.createElement("a");
    document.body.appendChild(downloadLink);
    downloadLink.style = "display: none";
    downloadLink.href = url;
    downloadLink.download = "react-webcam-stream-capture.webm";
    downloadLink.click();
    window.URL.revokeObjectURL(url);
    this.setState({ recordedChunks: [] });
  }

  render() {
    const { capturing, recordedChunks } = this.state;
    return (
      <>
        <Webcam audio={false} ref={this.webcamRef} />
        {capturing ? (
          <button onClick={this.handleStopCaptureClick}>Stop Capture</button>
        ) : (
          <button onClick={this.handleStartCaptureClick}>Start Capture</button>
        )}
        {recordedChunks.length > 0 && (
          <button onClick={this.handleDownload}>Download</button>
        )}
      </>
    );
  }
}

组件扩展说明

为了适配独立组件的复用需求,组件预留了两个对外回调接口:

  • onRecordingStart:录制流程正式启动时触发,可用于通知父组件切换按钮状态、展示录制提示
  • onDataReady:录制完成、生成可处理的视频Blob对象时触发,将Blob作为参数传入,父组件可直接用于上传、本地存储、二次编辑等自定义逻辑
  • 组件内置的下载按钮和对应逻辑不影响核心录制功能,可根据使用场景完全移除

内容的提问来源于stack exchange,提问作者galgo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.04 14:36:02