You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

视频流开发报错:Cannot set properties of undefined (setting 'srcObject')

解决React视频流中myVideo.current.srcObject赋值时的"Cannot set properties of undefined"错误

问题根源

报错的核心原因是myVideo.current未指向有效的<video> DOM元素,导致尝试设置srcObject时触发undefined异常。具体有两个关键诱因:

  • 未在JSX中把myVideo ref绑定到真实的<video>标签
  • useRef初始化方式错误,绑定DOM元素时应使用null而非空对象{}

修复步骤

1. 修正useRef初始化逻辑

将用于绑定DOM的useRef初始值改为null,这是React绑定DOM元素的标准写法:

const myVideo = useRef(null);  
const userVideo = useRef(null);  
const connectionRef = useRef();  

2. 在JSX中添加video元素并绑定ref

确保组件渲染出<video>标签,并将myVideo ref绑定到该元素上:

return (
  <div>
    <video ref={myVideo} autoPlay muted playsInline />
    {/* 其他组件内容 */}
  </div>
);
  • autoPlay:获取到媒体流后自动播放
  • muted:绕过浏览器自动播放限制(本地摄像头流静音不影响通话)
  • playsInline:适配移动端视频播放规则

3. 可选:添加DOM存在性校验

为避免异步操作中DOM尚未挂载的情况,可在赋值前增加校验逻辑:

navigator.mediaDevices
  .getUserMedia({ video: true, audio: true })
  .then((currentStream) => {
    setStream(currentStream);
    if (myVideo.current) {
      myVideo.current.srcObject = currentStream;
    }
  });

完整修正代码示例

import { useRef, useEffect, useState } from 'react';

function VideoCallComponent() {
  const myVideo = useRef(null);  
  const userVideo = useRef(null);  
  const connectionRef = useRef();
  const [stream, setStream] = useState(null);
  const [me, setMe] = useState('');
  const [call, setCall] = useState({});

  useEffect(() => {  
    navigator.mediaDevices  
      .getUserMedia({ video: true, audio: true })  
      .then((currentStream) => {  
        setStream(currentStream);  
        if (myVideo.current) {
          myVideo.current.srcObject = currentStream;
        }
      })
      .catch(err => {
        console.error('获取媒体设备失败:', err);
      });  

    socket.on("me", (id) => {  
      setMe(id);  
    });

    socket.on("callUser", ({ from, callerName, signal }) => {  
      setCall({ isReceivedCall: true, from, callerName, signal });  
    });  
  }, []);

  return (
    <div className="video-container">
      <video ref={myVideo} autoPlay muted playsInline className="local-video" />
      <video ref={userVideo} autoPlay playsInline className="remote-video" />
    </div>
  );
}

export default VideoCallComponent;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:31:05