与useEffect一起使用时,React Hook useRef为null

时间:2020-05-27 17:22:53

标签: javascript reactjs react-hooks webcam getusermedia

我想使用React Hook的useRef来设置视频流的src对象,但视频引用为null,并且出现错误: TypeError:无法在以下位置设置属性'srcObject'为null getMedia 。我正在使用useEffect来调用记录引用的函数。

奇怪的是,我同时看到null和当前值。查看控制台日志的屏幕截图:

screenshot

我已经阅读了useRef上的文档,并查看了Stack Overflow和Github上的所有其他帖子,但无法弄清楚。最近的帖子是this one。我在做什么错了?

简码:

const App = () => {
  const webcamRef = useRef(null)

  useEffect(() => {
    getMedia();
  }, [webcamRef])

  const getMedia = async () => {
    try {
      console.log(webcamRef);
      let stream = await navigator.mediaDevices.getUserMedia({ video: true });
      webcamRef.current.srcObject = stream;
    } catch (err) {
      console.error(err);
    }
  };

  return <video id='webcam' ref={webcamRef} />
}

完整代码: 沙盒:https://codesandbox.io/s/blissful-goldstine-rp9k5

1 个答案:

答案 0 :(得分:0)

根据您提供的代码,看来我的工作还不错。

我在效果中添加了webcamRef.current.play(),以便播放视频。

useEffect应该始终在组件完全安装(/渲染)之后运行,因此除非有条件地渲染视频,否则在效果运行时webcamRef.current不应为null。

此外,在useEffect中,您不应在依赖项数组中具有ref,因为它什么都不做,并且即使ref不变,它看起来也将重新触发效果。

https://codesandbox.io/s/inspiring-sara-9skhr?file=/src/App.js


JAM关于有条件渲染视频的更新:

您要做的主要事情是分离效果。您希望getMedia调用仅在视频元素在页面上时发生,否则webcamRef.current不能指向任何内容。

因此,在这种情况下,我将第一个效果集加载为true,然后创建了第二个效果,该效果使用loaded作为依赖项,以便在预处理完成后可以调用getMedia。

  useEffect(() => {
    const loadItems = async () => {
      console.log("preprocessing here");
    };  
    loadItems().then(() => {
      setLoadedStatus(true);
    });
  }, []);

  useEffect(() => {
    if (!loaded) return;
    const getMedia = async () => {
      try {
        console.log(webcamRef.current);
        let stream = await navigator.mediaDevices.getUserMedia({ video: true });
        webcamRef.current.srcObject = stream;
        webcamRef.current.play();
      } catch (err) {
        console.error(err);
      }
    };

    getMedia();
  }, [loaded]);

https://codesandbox.io/s/distracted-violet-s92d0?file=/src/App.js